<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Spring Boot从初识到实战 | JavaKeeper</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="icon" href="/icon.svg">
    <script>
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?a949a9b30eb86ac0159e735ff8670c03";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
            // 引入谷歌,不需要可删除这段
            var hm1 = document.createElement("script");
            hm1.src = "https://www.googletagmanager.com/gtag/js?id=UA-169923503-1";
            var s1 = document.getElementsByTagName("script")[0]; 
            s1.parentNode.insertBefore(hm1, s1);
        })();
        // 谷歌加载,不需要可删除
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-169923503-1');
    </script>
    <meta name="description" content="">
    <meta name="keywords" content="JavaKeeper,Java,Java开发,算法,blog">
    <link rel="preload" href="/assets/css/0.styles.91f57736.css" as="style"><link rel="preload" href="/assets/js/app.447d4224.js" as="script"><link rel="preload" href="/assets/js/3.9d76740c.js" as="script"><link rel="preload" href="/assets/js/1.c4fd7d2e.js" as="script"><link rel="preload" href="/assets/js/88.2a423212.js" as="script"><link rel="prefetch" href="/assets/js/10.8cf3be2c.js"><link rel="prefetch" href="/assets/js/100.74f35ab8.js"><link rel="prefetch" href="/assets/js/101.7a062346.js"><link rel="prefetch" href="/assets/js/102.c9485235.js"><link rel="prefetch" href="/assets/js/103.d88a3805.js"><link rel="prefetch" href="/assets/js/104.6e034144.js"><link rel="prefetch" href="/assets/js/105.d22f7450.js"><link rel="prefetch" href="/assets/js/106.a6cb54b0.js"><link rel="prefetch" href="/assets/js/107.7b65e72b.js"><link rel="prefetch" href="/assets/js/108.eb5804bb.js"><link rel="prefetch" href="/assets/js/109.05f775e5.js"><link rel="prefetch" href="/assets/js/11.c54ae13c.js"><link rel="prefetch" href="/assets/js/110.51d3d641.js"><link rel="prefetch" href="/assets/js/111.022b64a7.js"><link rel="prefetch" href="/assets/js/112.da8afd52.js"><link rel="prefetch" href="/assets/js/113.05a17b18.js"><link rel="prefetch" href="/assets/js/114.8960d913.js"><link rel="prefetch" href="/assets/js/115.67919f68.js"><link rel="prefetch" href="/assets/js/116.62b0cd71.js"><link rel="prefetch" href="/assets/js/117.ebac3eff.js"><link rel="prefetch" href="/assets/js/118.ecd629bd.js"><link rel="prefetch" href="/assets/js/119.a09a0897.js"><link rel="prefetch" href="/assets/js/12.60aa3b24.js"><link rel="prefetch" href="/assets/js/120.bf639d3d.js"><link rel="prefetch" href="/assets/js/121.b89d0c8e.js"><link rel="prefetch" href="/assets/js/122.1a75ff83.js"><link rel="prefetch" href="/assets/js/123.d2127132.js"><link rel="prefetch" href="/assets/js/124.2caff9e0.js"><link rel="prefetch" href="/assets/js/125.9b9f966a.js"><link rel="prefetch" href="/assets/js/126.58cdfb3d.js"><link rel="prefetch" href="/assets/js/127.8ef09c53.js"><link rel="prefetch" href="/assets/js/128.efdc2ae4.js"><link rel="prefetch" href="/assets/js/129.e35cbc57.js"><link rel="prefetch" href="/assets/js/13.125c13a0.js"><link rel="prefetch" href="/assets/js/130.f01a55e3.js"><link rel="prefetch" href="/assets/js/131.65205f4a.js"><link rel="prefetch" href="/assets/js/132.f42c5a0a.js"><link rel="prefetch" href="/assets/js/133.9ba468b3.js"><link rel="prefetch" href="/assets/js/134.7b597ba9.js"><link rel="prefetch" href="/assets/js/135.fb828b9a.js"><link rel="prefetch" href="/assets/js/136.3887532f.js"><link rel="prefetch" href="/assets/js/137.549bae01.js"><link rel="prefetch" href="/assets/js/138.db8d423d.js"><link rel="prefetch" href="/assets/js/139.dbaf2267.js"><link rel="prefetch" href="/assets/js/14.bd1d0b0d.js"><link rel="prefetch" href="/assets/js/140.6cb65fdc.js"><link rel="prefetch" href="/assets/js/141.9bd6cc4b.js"><link rel="prefetch" href="/assets/js/142.552db5ed.js"><link rel="prefetch" href="/assets/js/143.2c9f2bf4.js"><link rel="prefetch" href="/assets/js/144.fba98a15.js"><link rel="prefetch" href="/assets/js/145.c42f3a21.js"><link rel="prefetch" href="/assets/js/146.596d4d33.js"><link rel="prefetch" href="/assets/js/147.c48ae5c1.js"><link rel="prefetch" href="/assets/js/148.71064871.js"><link rel="prefetch" href="/assets/js/149.16582d21.js"><link rel="prefetch" href="/assets/js/15.f247873b.js"><link rel="prefetch" href="/assets/js/150.ead09aca.js"><link rel="prefetch" href="/assets/js/151.971fdf4b.js"><link rel="prefetch" href="/assets/js/152.369c9362.js"><link rel="prefetch" href="/assets/js/153.371edd15.js"><link rel="prefetch" href="/assets/js/154.e090b491.js"><link rel="prefetch" href="/assets/js/155.c68bf602.js"><link rel="prefetch" href="/assets/js/156.304aea8d.js"><link rel="prefetch" href="/assets/js/157.83beef7f.js"><link rel="prefetch" href="/assets/js/158.bb1794b0.js"><link rel="prefetch" href="/assets/js/159.2d54e792.js"><link rel="prefetch" href="/assets/js/16.04336c71.js"><link rel="prefetch" href="/assets/js/160.99d56586.js"><link rel="prefetch" href="/assets/js/161.edf660aa.js"><link rel="prefetch" href="/assets/js/162.0b84606e.js"><link rel="prefetch" href="/assets/js/163.b59e0d60.js"><link rel="prefetch" href="/assets/js/164.d9eb8228.js"><link rel="prefetch" href="/assets/js/165.ca624c79.js"><link rel="prefetch" href="/assets/js/166.025b2ba1.js"><link rel="prefetch" href="/assets/js/167.abc982cc.js"><link rel="prefetch" href="/assets/js/168.27ca13dc.js"><link rel="prefetch" href="/assets/js/169.41e753a2.js"><link rel="prefetch" href="/assets/js/17.43b3c1c8.js"><link rel="prefetch" href="/assets/js/170.626319e1.js"><link rel="prefetch" href="/assets/js/171.a221dddf.js"><link rel="prefetch" href="/assets/js/172.464b2361.js"><link rel="prefetch" href="/assets/js/173.96a3afee.js"><link rel="prefetch" href="/assets/js/174.116607c2.js"><link rel="prefetch" href="/assets/js/175.ea3e8659.js"><link rel="prefetch" href="/assets/js/176.7d7b8afc.js"><link rel="prefetch" href="/assets/js/177.a6e00aa0.js"><link rel="prefetch" href="/assets/js/178.1f93afaf.js"><link rel="prefetch" href="/assets/js/179.3aa00dcd.js"><link rel="prefetch" href="/assets/js/18.d81b44d5.js"><link rel="prefetch" href="/assets/js/180.f8b2b75a.js"><link rel="prefetch" href="/assets/js/181.8e11258a.js"><link rel="prefetch" href="/assets/js/182.22243941.js"><link rel="prefetch" href="/assets/js/183.d051fdf6.js"><link rel="prefetch" href="/assets/js/184.a994075e.js"><link rel="prefetch" href="/assets/js/185.776c7e16.js"><link rel="prefetch" href="/assets/js/186.f1887955.js"><link rel="prefetch" href="/assets/js/187.da0d3626.js"><link rel="prefetch" href="/assets/js/188.8dfc358f.js"><link rel="prefetch" href="/assets/js/189.dcac5a59.js"><link rel="prefetch" href="/assets/js/19.1b3d66e1.js"><link rel="prefetch" href="/assets/js/190.c7e413d0.js"><link rel="prefetch" href="/assets/js/191.d9806121.js"><link rel="prefetch" href="/assets/js/192.869791da.js"><link rel="prefetch" href="/assets/js/193.2d74c4c8.js"><link rel="prefetch" href="/assets/js/194.c73a1909.js"><link rel="prefetch" href="/assets/js/195.e8c74834.js"><link rel="prefetch" href="/assets/js/20.bd5949ec.js"><link rel="prefetch" href="/assets/js/21.3fcf98cf.js"><link rel="prefetch" href="/assets/js/22.2fa1e2e8.js"><link rel="prefetch" href="/assets/js/23.1ae64bb4.js"><link rel="prefetch" href="/assets/js/24.7bdf7387.js"><link rel="prefetch" href="/assets/js/25.392c436e.js"><link rel="prefetch" href="/assets/js/26.58acbd4b.js"><link rel="prefetch" href="/assets/js/27.c725bdd5.js"><link rel="prefetch" href="/assets/js/28.6c9bda1e.js"><link rel="prefetch" href="/assets/js/29.e656b537.js"><link rel="prefetch" href="/assets/js/30.2c326fc7.js"><link rel="prefetch" href="/assets/js/31.e6c9fa30.js"><link rel="prefetch" href="/assets/js/32.c9c88437.js"><link rel="prefetch" href="/assets/js/33.0c53373c.js"><link rel="prefetch" href="/assets/js/34.9821e543.js"><link rel="prefetch" href="/assets/js/35.de8253eb.js"><link rel="prefetch" href="/assets/js/36.d182f929.js"><link rel="prefetch" href="/assets/js/37.9fa79014.js"><link rel="prefetch" href="/assets/js/38.9bebff76.js"><link rel="prefetch" href="/assets/js/39.19a3a2d4.js"><link rel="prefetch" href="/assets/js/4.564edb9d.js"><link rel="prefetch" href="/assets/js/40.cca6955f.js"><link rel="prefetch" href="/assets/js/41.854cd09a.js"><link rel="prefetch" href="/assets/js/42.ca7b612f.js"><link rel="prefetch" href="/assets/js/43.87027d58.js"><link rel="prefetch" href="/assets/js/44.8c2b4f4b.js"><link rel="prefetch" href="/assets/js/45.dffb4e08.js"><link rel="prefetch" href="/assets/js/46.f58049a5.js"><link rel="prefetch" href="/assets/js/47.6854070c.js"><link rel="prefetch" href="/assets/js/48.6cd9fa3d.js"><link rel="prefetch" href="/assets/js/49.e8861afa.js"><link rel="prefetch" href="/assets/js/5.5c31d62f.js"><link rel="prefetch" href="/assets/js/50.703bffab.js"><link rel="prefetch" href="/assets/js/51.6655c373.js"><link rel="prefetch" href="/assets/js/52.deb2eb09.js"><link rel="prefetch" href="/assets/js/53.6e0ed77d.js"><link rel="prefetch" href="/assets/js/54.b05c58ad.js"><link rel="prefetch" href="/assets/js/55.49c8164e.js"><link rel="prefetch" href="/assets/js/56.a5574e6b.js"><link rel="prefetch" href="/assets/js/57.58cb0de4.js"><link rel="prefetch" href="/assets/js/58.52345112.js"><link rel="prefetch" href="/assets/js/59.663ce78d.js"><link rel="prefetch" href="/assets/js/6.a9df34ee.js"><link rel="prefetch" href="/assets/js/60.f06adde2.js"><link rel="prefetch" href="/assets/js/61.170255a1.js"><link rel="prefetch" href="/assets/js/62.9d120050.js"><link rel="prefetch" href="/assets/js/63.70cced6b.js"><link rel="prefetch" href="/assets/js/64.577f3548.js"><link rel="prefetch" href="/assets/js/65.c037b29d.js"><link rel="prefetch" href="/assets/js/66.7dd1045f.js"><link rel="prefetch" href="/assets/js/67.d3aa4d6c.js"><link rel="prefetch" href="/assets/js/68.526dbb61.js"><link rel="prefetch" href="/assets/js/69.58269266.js"><link rel="prefetch" href="/assets/js/7.6609d4d6.js"><link rel="prefetch" href="/assets/js/70.64108f1b.js"><link rel="prefetch" href="/assets/js/71.1e95e0a6.js"><link rel="prefetch" href="/assets/js/72.42e7ec94.js"><link rel="prefetch" href="/assets/js/73.dad4e1c5.js"><link rel="prefetch" href="/assets/js/74.28ea286a.js"><link rel="prefetch" href="/assets/js/75.dd6d4c6f.js"><link rel="prefetch" href="/assets/js/76.ca6539df.js"><link rel="prefetch" href="/assets/js/77.feb13b0e.js"><link rel="prefetch" href="/assets/js/78.321e90e6.js"><link rel="prefetch" href="/assets/js/79.68eb8fcf.js"><link rel="prefetch" href="/assets/js/8.396d51fd.js"><link rel="prefetch" href="/assets/js/80.4edb5321.js"><link rel="prefetch" href="/assets/js/81.735d7e57.js"><link rel="prefetch" href="/assets/js/82.fa120bdf.js"><link rel="prefetch" href="/assets/js/83.bf755f94.js"><link rel="prefetch" href="/assets/js/84.9b32070c.js"><link rel="prefetch" href="/assets/js/85.592aca7c.js"><link rel="prefetch" href="/assets/js/86.4dcd9e73.js"><link rel="prefetch" href="/assets/js/87.a9e546aa.js"><link rel="prefetch" href="/assets/js/89.5f455115.js"><link rel="prefetch" href="/assets/js/9.adb074c6.js"><link rel="prefetch" href="/assets/js/90.5202da0a.js"><link rel="prefetch" href="/assets/js/91.02cee99d.js"><link rel="prefetch" href="/assets/js/92.f16bad0b.js"><link rel="prefetch" href="/assets/js/93.f933634f.js"><link rel="prefetch" href="/assets/js/94.8e7b1d65.js"><link rel="prefetch" href="/assets/js/95.ee0e4a0a.js"><link rel="prefetch" href="/assets/js/96.e21d78c2.js"><link rel="prefetch" href="/assets/js/97.c87e514e.js"><link rel="prefetch" href="/assets/js/98.d123ac92.js"><link rel="prefetch" href="/assets/js/99.92d1b416.js">
    <link rel="stylesheet" href="/assets/css/0.styles.91f57736.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container no-sidebar" data-v-3ba18f14><div data-v-3ba18f14><div id="loader-wrapper" class="loading-wrapper" data-v-041fef5b data-v-3ba18f14 data-v-3ba18f14><div class="loader-main" data-v-041fef5b><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-68139a52 data-v-3ba18f14 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52>JavaKeeper</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div class="hide" data-v-3ba18f14><header class="navbar" data-v-3ba18f14><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">JavaKeeper</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask" data-v-3ba18f14></div> <aside class="sidebar" data-v-3ba18f14><div class="personal-info-wrapper" data-v-5f6acefd data-v-3ba18f14><!----> <h3 class="name" data-v-5f6acefd>
    海星
  </h3> <div class="num" data-v-5f6acefd><div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Article</h6></div> <div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Tag</h6></div></div> <hr data-v-5f6acefd></div> <nav class="nav-links"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <!----> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-68139a52 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52></h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div data-v-3ba18f14><main class="page"><div class="page-title" style="display:none;"><h1 class="title">Spring Boot从初识到实战</h1> <div data-v-5d8dbdb4><i class="iconfont reco-account" data-v-5d8dbdb4><span data-v-5d8dbdb4>海星</span></i> <!----> <!----> <!----></div></div> <div class="theme-reco-content content__default" style="display:none;"><h1 id="spring-boot从初识到实战"><a href="#spring-boot从初识到实战" class="header-anchor">#</a> Spring Boot从初识到实战</h1> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga26zho09tj20p00an0yr.jpg" alt="微信图片_20191219180720.png"></p> <blockquote><p>文章收集在 GitHub <a href="https://github.com/Jstarfish/JavaEgg" target="_blank" rel="noopener noreferrer">JavaEgg<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 中，欢迎star+指导</p> <p><a href="https://github.com/Jstarfish/JavaEgg" target="_blank" rel="noopener noreferrer">JavaEgg<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>——《“Java技术员”成长手册》，包含Java基础、框架、存储、搜索、优化、分布式等必备知识，N线互联网开发必备技能兵器谱。</p></blockquote> <h1 id="一、hello-spring-boot"><a href="#一、hello-spring-boot" class="header-anchor">#</a> 一、Hello Spring Boot</h1> <h3 id="_1、spring-boot-简介"><a href="#_1、spring-boot-简介" class="header-anchor">#</a> 1、Spring Boot 简介</h3> <ul><li>简化Spring应用开发的一个框架；</li> <li>整个Spring技术栈的一个大整合；</li> <li>J2EE开发的一站式解决方案；</li></ul> <h3 id="_2、微服务"><a href="#_2、微服务" class="header-anchor">#</a> 2、微服务</h3> <ul><li>微服务：架构风格（服务微化）</li> <li>一个应用应该是一组小型服务；可以通过HTTP的方式进行互通；</li> <li>单体应用：ALL IN ONE</li> <li>微服务：每一个功能元素最终都是一个可独立替换和独立升级的软件单元； <a href="https://martinfowler.com/articles/microservices.html#MicroservicesAndSoa" target="_blank" rel="noopener noreferrer">详细参照微服务文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h3 id="_3、环境准备"><a href="#_3、环境准备" class="header-anchor">#</a> <strong>3</strong>、环境准备</h3> <ul><li>jdk1.8：Spring Boot 推荐jdk1.7及以上；java version &quot;1.8.0_112&quot;</li> <li>maven3.x：maven 3.3以上版本；Apache Maven 3.3.9</li> <li>IntelliJIDEA、STS</li> <li>SpringBoot 2.2.2.RELEASE； 统一环境；</li></ul> <h4 id="_3-1、maven设置"><a href="#_3-1、maven设置" class="header-anchor">#</a> 3.1、MAVEN设置；</h4> <p>给maven 的settings.xml配置文件的proﬁles标签添加</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>profile</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>id</span><span class="token punctuation">&gt;</span></span>jdk‐1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>id</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>activation</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>activeByDefault</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>activeByDefault</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>jdk</span><span class="token punctuation">&gt;</span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>jdk</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>activation</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>properties</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>maven.compiler.source</span><span class="token punctuation">&gt;</span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>maven.compiler.source</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>maven.compiler.target</span><span class="token punctuation">&gt;</span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>maven.compiler.target</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>maven.compiler.compilerVersion</span><span class="token punctuation">&gt;</span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>maven.compiler.compilerVersion</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>properties</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>profile</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h4 id="_3-2、idea设置"><a href="#_3-2、idea设置" class="header-anchor">#</a> 3.2、IDEA设置</h4> <p>整合maven进来</p> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga23e64lm3j20vj0klgn4.jpg" alt="idea-maven.png"></p> <h4 id="_3-3、spring-boot-helloworld"><a href="#_3-3、spring-boot-helloworld" class="header-anchor">#</a> 3.3、Spring Boot HelloWorld</h4> <p>实现一个小功能：浏览器发送hello请求，服务器接受请求并处理，响应Hello World字符串；</p> <p><strong>1</strong>、创建一个<strong>maven</strong>工程；（<strong>jar</strong>）</p> <p><strong>2</strong>、导入<strong>spring boot</strong>相关的依赖</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.2.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>3</strong>、编写一个主程序；启动<strong>Spring Boot</strong>应用</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
* @SpringBootApplication 来标注一个主程序类，说明这是一个Spring Boot应用
*/</span>
<span class="token annotation punctuation">@SpringBootApplication</span>
	<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloWorldMainApplication</span> <span class="token punctuation">{</span>
	<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// Spring应用启动起来</span>
 	<span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">HelloWorldMainApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><p><strong>4</strong>、编写相关的<strong>Controller</strong>、<strong>Service</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Controller</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloController</span> <span class="token punctuation">{</span>
        <span class="token annotation punctuation">@ResponseBody</span>
        <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/hello&quot;</span><span class="token punctuation">)</span>
        <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token string">&quot;Hello World!&quot;</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</code></pre></div><p><strong>5</strong>、运行主程序main方法，测试</p> <p>​	<img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga0oyjprn6j20i104mweg.jpg" alt="springboot-hello.png"></p> <p><strong>6</strong>、简化部署</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span> <span class="token attr-name">这个插件，可以将应用打包成一个可执行的jar包；‐‐</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>build</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugins</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugin</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐maven‐plugin<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugin</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugins</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>build</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>将这个应用打成jar包，直接使用java -jar的命令进行执行<code>java -jar HelloWorldMainApplication.jar</code></p> <h4 id="_3-4、hello-world探究"><a href="#_3-4、hello-world探究" class="header-anchor">#</a> <strong>3.4</strong>、Hello World探究</h4> <h5 id="_3-4-1、pom文件"><a href="#_3-4-1、pom文件" class="header-anchor">#</a> 3.4.1、POM文件</h5> <ol><li><p>父项目</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.2.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>进入父项目，可以看到父项目的父项目（爷项目）</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token comment">&lt;!-- 爷爷项目(他的父项目）是 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐dependencies<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.2.2.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>relativePath</span><span class="token punctuation">&gt;</span></span>../../spring‐boot‐dependencies<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>relativePath</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>他来真正管理Spring Boot应用里面的所有依赖版本；是<strong>Spring Boot的版本仲裁中心</strong>；</p> <p><strong>以后我们导入依赖默认是不需要写版本的</strong>；（没有在dependencies里面管理的依赖自然需要声明版本号）</p></li> <li><p>启动器</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div></li></ol> <p>​       <strong>spring-boot-starter-web</strong>：</p> <p>​		spring-boot-starter：spring-boot场景启动器；帮我们导入了web模块正常运行所依赖的组件；</p> <p>​		Spring Boot将所有的功能场景都抽取出来，做成一个个的starters（启动器），只需要在项目里面引入这些		starter</p> <p>​		相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器</p> <h5 id="_3-4-2、主程序类-主入口类-跟着假装点进去-看看源码-成为一个看过源码的初学者"><a href="#_3-4-2、主程序类-主入口类-跟着假装点进去-看看源码-成为一个看过源码的初学者" class="header-anchor">#</a> 3.4.2、主程序类，主入口类（跟着假装点进去，看看源码，成为一个看过源码的初学者）</h5> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
 * @SpringBootApplication 来标注一个主程序类，说明这是一个Spring Boot应用
 */</span>
<span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloWorldMainApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Spring应用启动起来</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">HelloWorldMainApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><p>@<strong>SpringBootApplication</strong>: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类，SpringBoot</p> <p>就应该运行这个类的main方法来启动SpringBoot应用；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Target</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token class-name">ElementType</span><span class="token punctuation">.</span>TYPE<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Retention</span><span class="token punctuation">(</span><span class="token class-name">RetentionPolicy</span><span class="token punctuation">.</span>RUNTIME<span class="token punctuation">)</span>
<span class="token annotation punctuation">@Documented</span>
<span class="token annotation punctuation">@Inherited</span>
<span class="token annotation punctuation">@SpringBootConfiguration</span>
<span class="token annotation punctuation">@EnableAutoConfiguration</span>
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span>
    excludeFilters <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token annotation punctuation">@Filter</span><span class="token punctuation">(</span>
    type <span class="token operator">=</span> <span class="token class-name">FilterType</span><span class="token punctuation">.</span>CUSTOM<span class="token punctuation">,</span>
    classes <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token class-name">TypeExcludeFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token annotation punctuation">@Filter</span><span class="token punctuation">(</span>
    type <span class="token operator">=</span> <span class="token class-name">FilterType</span><span class="token punctuation">.</span>CUSTOM<span class="token punctuation">,</span>
    classes <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token class-name">AutoConfigurationExcludeFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">SpringBootApplication</span> <span class="token punctuation">{</span>
</code></pre></div><p>@<strong>SpringBootConﬁguration</strong>:Spring Boot的配置类； 标注在某个类上，表示这是一个Spring   Boot的配置类；</p> <p>@<strong>Conﬁguration</strong>:用来标注这是个配置类；</p> <p>@<strong>EnableAutoConﬁguration</strong>：开启自动配置功能；</p> <p>以前我们需要配置的东西，Spring  Boot帮我们自动配置；@<strong>EnableAutoConﬁguration</strong>告诉SpringBoot开启自动配置功能；这样自动配置才能生效；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@AutoConfigurationPackage</span>
<span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token class-name">AutoConfigurationImportSelector</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">EnableAutoConfiguration</span> <span class="token punctuation">{</span>
</code></pre></div><p>@<strong>AutoConﬁgurationPackage</strong>：自动配置包</p> <p>Spring的底层注解**@Import**，给容器中导入一个组件；导入的组件由AutoConfigurationImportSelector.class</p> <p>将主配置类（@SpringBootApplication标注的类）的所在包及下面所有子包里面的所有组件扫描到Spring容器；</p> <p><strong>@Import</strong>(EnableAutoConﬁgurationImportSelector.class)； 给容器中导入组件？</p> <p><strong>AutoConfigurationImportSelector</strong>：导入哪些组件的选择器；</p> <p>将所有需要导入的组件以全类名的方式返回；这些组件就会被添加到容器中；</p> <p>会给容器中导入非常多的自动配置类（xxxAutoConﬁguration）；就是给容器中导入这个场景需要的所有组件， 并配置好这些组件；</p> <p>有了自动配置类，免去了我们手动编写配置注入功能组件等的工作；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token class-name">SpringFactoriesLoader</span><span class="token punctuation">.</span><span class="token function">loadFactoryNames</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getSpringFactoriesLoaderFactoryClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getBeanClassLoader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Spring Boot在启动的时候从类路径下的<strong>META-INF/spring.factories</strong>中获取EnableAutoConﬁguration指定的值，将这些值作为自动配置类导入到容器中，自动配置类就生效，帮我们进行自动配置工作；以前我们需要自己配置的东西，自动配置类都帮我们配置好了；</p> <p>J2EE的整体整合解决方案和自动配置都在spring-boot-autoconﬁgure-2.2.2.RELEASE.jar；</p> <h4 id="_3-5、使用spring-initializer快速创建spring-boot项目"><a href="#_3-5、使用spring-initializer快速创建spring-boot项目" class="header-anchor">#</a> 3.5、使用Spring Initializer快速创建Spring Boot项目</h4> <ol><li><p>IDEA：可以使用 <strong>Spring Initializer</strong>快速创建项目</p> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga0q1zzjupj20mi0a4gm1.jpg" alt="idea-initializer.png"></p> <p>IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目； 选择我们需要的模块；向导会联网创建Spring Boot项目；</p> <p>默认生成的Spring Boot项目；</p> <ul><li>主程序已经生成好了，我们只需要我们自己的逻辑</li> <li>resources文件夹中目录结构</li> <li>static：保存所有的静态资源； js css images；</li> <li>templates：保存所有的模板页面；（Spring Boot默认jar包使用嵌入式的Tomcat，默认不支持JSP页面）；可以使用模板引擎（freemarker、thymeleaf）；</li> <li>application.properties：Spring Boot应用的配置文件；可以修改一些默认设置；</li></ul></li> <li><p><strong>STS</strong>使用 <strong>Spring Starter Project</strong>快速创建项目</p></li></ol> <hr> <h1 id="二、配置文件"><a href="#二、配置文件" class="header-anchor">#</a> 二、配置文件</h1> <h2 id="_1、配置文件"><a href="#_1、配置文件" class="header-anchor">#</a> <strong>1</strong>、配置文件</h2> <p>SpringBoot使用一个全局的配置文件，配置文件名是固定的(有两种形式)；</p> <ul><li><strong>application.properties</strong></li> <li><strong>application.yml</strong></li></ul> <p>配置文件的作用：修改SpringBoot自动配置的默认值；(SpringBoot在底层都给我们自动配置好了)</p> <p><strong>YAML</strong>（YAML Ain't Markup Language） YAML A Markup Language：是一个<strong>标记语言</strong></p> <p>YAML：以数据为中心，比json、xml等更适合做配置文件；</p> <p>以前的配置文件；大多都使用的是 <strong>xxxx.xml</strong>文件；eg:</p> <p>YAML：配置例子</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080</span>
</code></pre></div><p>XML例子：</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>server</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>port</span><span class="token punctuation">&gt;</span></span>8080<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>port</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>server</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h2 id="_2、yaml语法"><a href="#_2、yaml语法" class="header-anchor">#</a> 2、YAML语法：</h2> <h3 id="_1、基本语法"><a href="#_1、基本语法" class="header-anchor">#</a> 1、基本语法</h3> <p>k:(空格)v：表示一对键值对（空格必须有）；</p> <p>以空格的缩进来控制层级关系；只要是左对齐的一列数据，都是同一个层级的</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>
	<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080</span>
	<span class="token key atrule">path</span><span class="token punctuation">:</span> /hello
</code></pre></div><p><mark>属性和值是大小写敏感的</mark>；</p> <h3 id="_2、值的写法"><a href="#_2、值的写法" class="header-anchor">#</a> 2、值的写法</h3> <h4 id="字面量-普通的值-数字-字符串-布尔"><a href="#字面量-普通的值-数字-字符串-布尔" class="header-anchor">#</a> 字面量：普通的值（数字，字符串，布尔）</h4> <p>k: v：字面直接来写；</p> <p>字符串默认不用加上单引号或者双引号；</p> <p><code>&quot;&quot;</code>：双引号；不会转义字符串里面的特殊字符；特殊字符会作为本身想表示的意思name: &quot;zhangsan \n lisi&quot;：输出；zhangsan 换行 lisi</p> <p><code>''</code>：单引号；会转义特殊字符，特殊字符最终只是一个普通的字符串数据</p> <p>name: ‘zhangsan \n lisi’：输出；zhangsan \n lisi</p> <h4 id="对象、map-属性和值-键值对"><a href="#对象、map-属性和值-键值对" class="header-anchor">#</a> 对象、Map（属性和值）（键值对）：</h4> <p>k: v</p> <p>：在下一行来写对象的属性和值的关系；注意缩进</p> <p>对象还是k: v的方式</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">friends</span><span class="token punctuation">:</span>
	<span class="token key atrule">lastName</span><span class="token punctuation">:</span> zhangsan
	<span class="token key atrule">age</span><span class="token punctuation">:</span> <span class="token number">20</span>	
</code></pre></div><p>行内写法：</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">friends</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token key atrule">lastName</span><span class="token punctuation">:</span> zhangsan<span class="token punctuation">,</span><span class="token key atrule">age</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">}</span>
</code></pre></div><h4 id="数组-list、set"><a href="#数组-list、set" class="header-anchor">#</a> 数组（List、Set）：</h4> <p>用<code>-</code>值表示数组中的一个元素</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">pets</span><span class="token punctuation">:</span>
  ‐ cat
  ‐ dog
  ‐ pig
</code></pre></div><p>行内写法</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">pets</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>cat<span class="token punctuation">,</span>dog<span class="token punctuation">,</span>pig<span class="token punctuation">]</span>
</code></pre></div><h2 id="_3、配置文件值注入"><a href="#_3、配置文件值注入" class="header-anchor">#</a> <strong>3</strong>、配置文件值注入</h2> <h3 id="_3-1、配置文件"><a href="#_3-1、配置文件" class="header-anchor">#</a> 3.1、配置文件:</h3> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">person</span><span class="token punctuation">:</span>
	<span class="token key atrule">lastName</span><span class="token punctuation">:</span> hello
	<span class="token key atrule">age</span><span class="token punctuation">:</span> <span class="token number">18</span>
	<span class="token key atrule">boss</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>
	<span class="token key atrule">birth</span><span class="token punctuation">:</span> 2017/12/12
	<span class="token key atrule">maps</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token key atrule">k1</span><span class="token punctuation">:</span> v1<span class="token punctuation">,</span><span class="token key atrule">k2</span><span class="token punctuation">:</span> <span class="token number">12</span><span class="token punctuation">}</span>
	<span class="token key atrule">lists</span><span class="token punctuation">:</span>
		‐ lisi
		‐ zhaoliu
	<span class="token key atrule">dog</span><span class="token punctuation">:</span>
		<span class="token key atrule">name</span><span class="token punctuation">:</span> 小狗
		<span class="token key atrule">age</span><span class="token punctuation">:</span> <span class="token number">12</span>
</code></pre></div><h3 id="_3-2、javabean"><a href="#_3-2、javabean" class="header-anchor">#</a> 3.2、javaBean：</h3> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
* 将配置文件中配置的每一个属性的值，映射到这个组件中
* @ConfigurationProperties：告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定；
* prefix = &quot;person&quot;：配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件，才能使用容器提供的@ConfigurationProperties功能；
*
*/</span>
<span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;person&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
  <span class="token keyword">private</span> <span class="token class-name">String</span> lastName<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">Boolean</span> boss<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">Date</span> birth<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> maps<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> lists<span class="token punctuation">;</span>
  <span class="token keyword">private</span> <span class="token class-name">Dog</span> dog<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>我们可以导入配置文件处理器，以后编写配置就有提示了</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐导入配置文件处理器，配置文件进行绑定就会有提示‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐configuration‐processor<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>optional</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>optional</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_3-3、-value获取值和-configurationproperties获取值的区别"><a href="#_3-3、-value获取值和-configurationproperties获取值的区别" class="header-anchor">#</a> 3.3、@Value获取值和@ConﬁgurationProperties获取值的区别</h3> <table><thead><tr><th></th> <th><strong>@ConﬁgurationProperties</strong></th> <th><strong>@Value</strong></th></tr></thead> <tbody><tr><td>功能</td> <td>批量注入配置文件中的属性</td> <td>一个个指定</td></tr> <tr><td>松散绑定（松散语法）</td> <td>支持</td> <td>不支持</td></tr> <tr><td>SpEL</td> <td>不支持</td> <td>支持</td></tr> <tr><td>JSR303数据校验</td> <td>支持</td> <td>不支持</td></tr> <tr><td>复杂类型封装</td> <td>支持</td> <td>不支持</td></tr></tbody></table> <ul><li><p>配置文件yml还是properties他们都能获取到值；</p></li> <li><p>如果说，我们只是在某个业务逻辑中需要获取一下配置文件中的某项值，使用@Value；</p></li> <li><p>如果说，我们专门编写了一个javaBean来和配置文件进行映射，我们就直接使用@ConﬁgurationProperties；</p></li></ul> <h3 id="_3-4、配置文件注入值数据校验"><a href="#_3-4、配置文件注入值数据校验" class="header-anchor">#</a> <strong>3</strong>.4、配置文件注入值数据校验</h3> <div class="language-java extra-class"><pre class="language-java"><code> <span class="token annotation punctuation">@Component</span>
 <span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;person&quot;</span><span class="token punctuation">)</span>
 <span class="token annotation punctuation">@Validated</span>
 <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
    <span class="token comment">/**
      * &lt;bean class=&quot;Person&quot;&gt;
      * &lt;property name=&quot;lastName&quot; value=&quot;字面量/${key}从环境变量、配置文件中获取值/#
      	{SpEL}&quot;&gt;&lt;/property&gt;
      * &lt;bean/&gt;
      */</span>
    <span class="token comment">//lastName必须是邮箱格式</span>
    <span class="token annotation punctuation">@Email</span>
    <span class="token comment">//@Value(&quot;${person.last‐name}&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> lastName<span class="token punctuation">;</span>
    <span class="token comment">//@Value(&quot;#{11*2}&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token comment">//@Value(&quot;true&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">Boolean</span> boss<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Date</span> birth<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> maps<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> lists<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Dog</span> dog<span class="token punctuation">;</span>
 <span class="token punctuation">}</span>
</code></pre></div><h3 id="_3-5、-propertysource-importresource-bean"><a href="#_3-5、-propertysource-importresource-bean" class="header-anchor">#</a> <strong>3.5</strong>、@PropertySource&amp;@ImportResource&amp;@Bean</h3> <p>@<strong>PropertySource</strong>：加载指定的配置文件；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
* 将配置文件中配置的每一个属性的值，映射到这个组件中
* @ConfigurationProperties：告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定；
* prefix = &quot;person&quot;：配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件，才能容器提供的@ConfigurationProperties功能；
* @ConfigurationProperties(prefix = &quot;person&quot;)默认从全局配置文件中获取值；
*
*/</span>
<span class="token annotation punctuation">@PropertySource</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">&quot;classpath:person.properties&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;person&quot;</span><span class="token punctuation">)</span>
<span class="token comment">//@Validated</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span>
    <span class="token comment">/**
    * &lt;bean class=&quot;Person&quot;&gt;
    * &lt;property name=&quot;lastName&quot; value=&quot;字面量/${key}从环境变量、配置文件中获取值/#
    {SpEL}&quot;&gt;&lt;/property&gt;
    * &lt;bean/&gt;
    */</span>
    <span class="token comment">//lastName必须是邮箱格式</span>
    <span class="token comment">// @Email</span>
    <span class="token comment">//@Value(&quot;${person.last‐name}&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> lastName<span class="token punctuation">;</span>
    <span class="token comment">//@Value(&quot;#{11*2}&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token comment">//@Value(&quot;true&quot;)</span>
    <span class="token keyword">private</span> <span class="token class-name">Boolean</span> boss<span class="token punctuation">;</span><span class="token punctuation">}</span>
</code></pre></div><p>@<strong>ImportResource</strong>：导入Spring的配置文件，让配置文件里面的内容生效；</p> <p>Spring Boot里面没有Spring的配置文件，我们自己编写的配置文件，也不能自动识别； 想让Spring</p> <p>的配置文件生效，加载进来；需要将@ImportResource标注在一个配置类上，导入Spring的配置文件让其生效</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ImportResource</span><span class="token punctuation">(</span>locations <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">&quot;classpath:beans.xml&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>自定义的Spring配置文件</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF‐8&quot;?&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/beans<span class="token punctuation">&quot;</span></span>
<span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.w3.org/2001/XMLSchema‐instance<span class="token punctuation">&quot;</span></span>
<span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring‐beans.xsd<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>helloService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.atguigu.springboot.service.HelloService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>beans</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>SpringBoot推荐给容器中添加组件的方式；推荐使用全注解的方式</p> <ol><li><p>配置类**@Conﬁguration**------&gt;Spring配置文件</p></li> <li><p>使用**@Bean**给容器中添加组件</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
* @Configuration：指明当前类是一个配置类；就是来替代之前的Spring配置文件
* 在配置文件中用&lt;bean&gt;&lt;bean/&gt;标签添加组件
*/</span>
<span class="token annotation punctuation">@Configuration</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyAppConfig</span> <span class="token punctuation">{</span>
    <span class="token comment">//将方法的返回值添加到容器中；容器中这个组件默认的id就是方法名</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">HelloService</span> <span class="token function">helloService02</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;配置类@Bean给容器中添加组件了...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">HelloService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ol> <h3 id="_3-6、配置文件占位符"><a href="#_3-6、配置文件占位符" class="header-anchor">#</a> <strong>3.6</strong>、配置文件占位符</h3> <p><strong>1</strong>、随机数</p> <div class="language-java extra-class"><pre class="language-java"><code>$<span class="token punctuation">{</span>random<span class="token punctuation">.</span>value<span class="token punctuation">}</span>、$<span class="token punctuation">{</span>random<span class="token punctuation">.</span><span class="token keyword">int</span><span class="token punctuation">}</span>、$<span class="token punctuation">{</span>random<span class="token punctuation">.</span><span class="token keyword">long</span><span class="token punctuation">}</span>
$<span class="token punctuation">{</span>random<span class="token punctuation">.</span><span class="token keyword">int</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">}</span>、$<span class="token punctuation">{</span>random<span class="token punctuation">.</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">1024</span><span class="token punctuation">,</span><span class="token number">65536</span><span class="token punctuation">]</span><span class="token punctuation">}</span>
</code></pre></div><p><strong>2</strong>、占位符获取之前配置的值，如果没有可以是用 <code>:</code> 指定默认值</p> <div class="language-properties extra-class"><pre class="language-properties"><code><span class="token attr-name">person.last‐name</span><span class="token punctuation">=</span><span class="token attr-value">张三${random.uuid}</span>
<span class="token attr-name">person.age</span><span class="token punctuation">=</span><span class="token attr-value">${random.int}</span>
<span class="token attr-name">person.birth</span><span class="token punctuation">=</span><span class="token attr-value">2017/12/15</span>
<span class="token attr-name">person.boss</span><span class="token punctuation">=</span><span class="token attr-value">false</span>
<span class="token attr-name">person.maps.k1</span><span class="token punctuation">=</span><span class="token attr-value">v1</span>
<span class="token attr-name">person.maps.k2</span><span class="token punctuation">=</span><span class="token attr-value">14</span>
<span class="token attr-name">person.lists</span><span class="token punctuation">=</span><span class="token attr-value">a,b,c</span>
<span class="token attr-name">person.dog.name</span><span class="token punctuation">=</span><span class="token attr-value">${person.hello:hello}_dog</span>
<span class="token attr-name">person.dog.age</span><span class="token punctuation">=</span><span class="token attr-value">15</span>
</code></pre></div><h3 id="_3-7、profile"><a href="#_3-7、profile" class="header-anchor">#</a> 3.7、Proﬁle</h3> <h4 id="_3-7-1、多profile文件"><a href="#_3-7-1、多profile文件" class="header-anchor">#</a> 3.7.1、多Proﬁle文件</h4> <p>我们在主配置文件编写的时候，文件名可以是 <strong>application-{proﬁle}.properties/yml</strong></p> <p>默认使用application.properties的配置；</p> <h4 id="_3-7-2、yml支持多文档块方式"><a href="#_3-7-2、yml支持多文档块方式" class="header-anchor">#</a> 3.7.2、yml支持多文档块方式</h4> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>
	<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8081</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
	<span class="token key atrule">profiles</span><span class="token punctuation">:</span>
	<span class="token key atrule">active</span><span class="token punctuation">:</span> prod
‐‐‐
<span class="token key atrule">server</span><span class="token punctuation">:</span>
	<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8083</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
	<span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev
‐‐‐
<span class="token key atrule">server</span><span class="token punctuation">:</span>
	<span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8084</span>
	<span class="token key atrule">spring</span><span class="token punctuation">:</span>
<span class="token key atrule">profiles</span><span class="token punctuation">:</span> prod <span class="token comment">#指定属于哪个环境</span>

</code></pre></div><h4 id="_3-7-3、激活指定profile"><a href="#_3-7-3、激活指定profile" class="header-anchor">#</a> 3.7.3、激活指定proﬁle</h4> <p>1、在配置文件中指定 <strong>spring.proﬁles.active=dev</strong></p> <p>2、命令行：</p> <p><code>java -jar spring-boot-02-conﬁg-0.0.1-SNAPSHOT.jar --spring.proﬁles.active=dev</code>； 可以直接在测试的时候，配置传入命令行参数</p> <p>3、虚拟机参数；</p> <p><code>-Dspring.proﬁles.active=dev</code></p> <h3 id="_3-8、配置文件加载位置"><a href="#_3-8、配置文件加载位置" class="header-anchor">#</a> 3.8、配置文件加载位置</h3> <p>springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件</p> <ul><li>ﬁle:./conﬁg/</li> <li>ﬁle:./</li> <li>classpath:/conﬁg/</li> <li>classpath:/</li></ul> <p><mark>优先级由高到底，高优先级的配置会覆盖低优先级的配置；</mark></p> <p>SpringBoot会从这四个位置全部加载主配置文件；互补配置；</p> <p>我们还可以通过<strong>spring.conﬁg.location</strong>来改变默认的配置文件位置</p> <p>项目打包好以后，我们可以使用命令行参数的形式，启动项目的时候来指定配置文件的新位置；指定配置文件和默  认加载的这些配置文件共同起作用形成互补配置；</p> <p><code>java -jar spring-boot-02-conﬁg-02-0.0.1-SNAPSHOT.jar --spring.conﬁg.location=G:/application.properties</code></p> <h3 id="_3-9、外部配置加载顺序"><a href="#_3-9、外部配置加载顺序" class="header-anchor">#</a> 3.9、外部配置加载顺序</h3> <p><strong>SpringBoot</strong>也可以从以下位置加载配置；   优先级从高到低；高优先级的配置覆盖低优先级的配置，所有的配置会形成互补配置</p> <ol><li><p>命令行参数</p> <p>所有的配置都可以在命令行上进行指定</p> <p><code>java -jar spring-boot-02-conﬁg-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc</code></p> <p>多个配置用空格分开； <strong>--配置项=值</strong></p></li> <li><p>来 自 java:comp/env 的 JNDI 属 性</p></li> <li><p>Java系统属性（System.getProperties()）</p></li> <li><p>操作系统环境变量</p></li> <li><p>RandomValuePropertySource配置的random.*属性值</p></li></ol> <p>由<strong>jar</strong>包外向<strong>jar</strong>包内进行寻找；优先加载带<strong>proﬁle</strong></p> <ol start="6"><li><strong>jar</strong>包外部的<strong>application-{proﬁle}.properties</strong>或**application.yml(<strong>带</strong>spring.proﬁle)**配置文件</li> <li><strong>jar</strong>包内部的<strong>application-{proﬁle}.properties</strong>或**application.yml(<strong>带</strong>spring.proﬁle)**配置文件</li></ol> <p>再来加载不带<strong>proﬁle</strong></p> <ol start="8"><li><p>jar包外部的application.properties或application.yml(不带spring.proﬁle)配置文件</p></li> <li><p><strong>jar</strong>包内部的<strong>application.properties</strong>或**application.yml(<strong>不带</strong>spring.proﬁle)**配置文件</p></li></ol> <p>10.@Conﬁguration注解类上的@PropertySource</p> <p>11.通过SpringApplication.setDefaultProperties指定的默认属性所有支持的配置加载来源；</p> <p><a href="https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#boot-features-external-config" target="_blank" rel="noopener noreferrer">参考官方文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h3 id="_3-10、自动配置原理"><a href="#_3-10、自动配置原理" class="header-anchor">#</a> 3.10、自动配置原理</h3> <p>配置文件到底能写什么？怎么写？自动配置原理； <a href="https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#common-application-properties" target="_blank" rel="noopener noreferrer">配置文件能配置的属性参照<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h4 id="_3-10-1、自动配置原理"><a href="#_3-10-1、自动配置原理" class="header-anchor">#</a> 3.10.1、自动配置原理：</h4> <p>1）、SpringBoot启动的时候加载主配置类，开启了自动配置功能 @EnableAutoConﬁguration</p> <p>2）、<strong>@EnableAutoConﬁguration</strong> 作用：</p> <ul><li><p>利用AutoConfigurationImportSelector给容器中导入一些组件</p></li> <li><p>可以查看selectImports()方法的内容；</p></li> <li><p>List conﬁgurations = getCandidateConﬁgurations(annotationMetadata, attributes);获取候选的配置</p> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga0towma6lj211c0hz0yw.jpg" alt="autoConfigurate.png"></p></li></ul> <div class="language-java extra-class"><pre class="language-java"><code><span class="token class-name">SpringFactoriesLoader</span><span class="token punctuation">.</span><span class="token function">loadFactoryNames</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><p>扫描所有jar包类路径下  <code>META‐INF/spring.factories</code>，把扫描到的这些文件的内容包装成properties对象
从properties中获取到 <code>EnableAutoConfiguration.class</code>类（类名）对应的值，然后把他们添加在容器
中</p> <p>将类路径下 <strong>META-INF/spring.factories</strong> 里面配置的所有<strong>EnableAutoConﬁguration</strong>的值加入到了容器中；</p> <div class="language-xml extra-class"><pre class="language-xml"><code># Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration
,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration
,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration
</code></pre></div><p>每一个这样的  xxxAutoConﬁguration类都是容器中的一个组件，都加入到容器中；用他们来做自动配置；</p> <p>3）、每一个自动配置类进行自动配置功能；</p> <p>4）、以HttpEncodingAutoConﬁguration（Http编码自动配置）为例解释自动配置原理；</p> <div class="language-java extra-class"><pre class="language-java"><code>    <span class="token annotation punctuation">@Configuration</span>  <span class="token comment">//表示这是一个配置类，以前编写的配置文件一样，也可以给容器中添加组件</span>
    <span class="token annotation punctuation">@EnableConfigurationProperties</span><span class="token punctuation">(</span><span class="token class-name">HttpEncodingProperties</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">//启动指定类的</span>
    <span class="token comment">//ConfigurationProperties功能；将配置文件中对应的值和HttpEncodingProperties绑定起来；并把</span>
     <span class="token comment">//       HttpEncodingProperties加入到ioc容器中</span>
    <span class="token annotation punctuation">@ConditionalOnWebApplication</span> <span class="token comment">//Spring底层@Conditional注解（Spring注解版），根据不同的条件，如     //果满足指定的条件，整个配置类里面的配置就会生效； 判断当前应用是否是web应用，如果是，当前配置类生效</span>
    <span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token class-name">CharacterEncodingFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">//判断当前项目有没有这个类</span>
      <span class="token comment">// CharacterEncodingFilter；SpringMVC中进行乱码解决的过滤器；</span>
    <span class="token annotation punctuation">@ConditionalOnProperty</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.http.encoding&quot;</span><span class="token punctuation">,</span> value <span class="token operator">=</span> <span class="token string">&quot;enabled&quot;</span><span class="token punctuation">,</span> matchIfMissing <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment">//判断配置文件中是否存在某个配置 spring.http.encoding.enabled；如果不存在，判断也是成立的即使我们配置文件中不配置pring.http.encoding.enabled=true，也是默认生效的；</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HttpEncodingAutoConfiguration</span> <span class="token punctuation">{</span>
        <span class="token comment">//他已经和SpringBoot的配置文件映射了</span>
        <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">HttpEncodingProperties</span> properties<span class="token punctuation">;</span>
        <span class="token comment">//只有一个有参构造器的情况下，参数的值就会从容器中拿</span>
        <span class="token keyword">public</span> <span class="token class-name">HttpEncodingAutoConfiguration</span><span class="token punctuation">(</span><span class="token class-name">HttpEncodingProperties</span> properties<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>properties <span class="token operator">=</span> properties<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token annotation punctuation">@Bean</span> <span class="token comment">//给容器中添加一个组件，这个组件的某些值需要从properties中获取</span>
        <span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span><span class="token class-name">CharacterEncodingFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token comment">//判断容器没有这个组件？</span>
        <span class="token keyword">public</span> <span class="token class-name">CharacterEncodingFilter</span> <span class="token function">characterEncodingFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token class-name">CharacterEncodingFilter</span> filter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">OrderedCharacterEncodingFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            filter<span class="token punctuation">.</span><span class="token function">setEncoding</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>properties<span class="token punctuation">.</span><span class="token function">getCharset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            filter<span class="token punctuation">.</span><span class="token function">setForceRequestEncoding</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>properties<span class="token punctuation">.</span><span class="token function">shouldForce</span><span class="token punctuation">(</span><span class="token class-name">Type</span><span class="token punctuation">.</span>REQUEST<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            filter<span class="token punctuation">.</span><span class="token function">setForceResponseEncoding</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>properties<span class="token punctuation">.</span><span class="token function">shouldForce</span><span class="token punctuation">(</span><span class="token class-name">Type</span><span class="token punctuation">.</span>RESPONSE<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> filter<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
</code></pre></div><p>根据当前不同的条件判断，决定这个配置类是否生效</p> <p>一但这个配置类生效；这个配置类就会给容器中添加各种组件；这些组件的属性是从对应的properties类中获取 的，这些类里面的每一个属性又是和配置文件绑定的；</p> <p>5）、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘；配置文件能配置什么就可以参照某个功 能对应的这个属性类</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.http.encoding&quot;</span><span class="token punctuation">)</span> <span class="token comment">//从配置文件中获取指定的值和bean的属</span>
性进行绑定
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HttpEncodingProperties</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Charset</span> DEFAULT_CHARSET <span class="token operator">=</span> <span class="token class-name">Charset</span><span class="token punctuation">.</span><span class="token function">forName</span><span class="token punctuation">(</span><span class="token string">&quot;UTF‐8&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>精髓：</p> <p><strong>1</strong>）、<strong>SpringBoot</strong>启动会加载大量的自动配置类</p> <p><strong>2</strong>）、我们看我们需要的功能有没有<strong>SpringBoot</strong>默认写好的自动配置类；</p> <p><strong>3</strong>）、我们再来看这个自动配置类中到底配置了哪些组件；（只要我们要用的组件有，我们就不需要再来配置了）</p> <p><strong>4</strong>）、给容器中自动配置类添加组件的时候，会从<strong>properties</strong>类中获取某些属性。我们就可以在配置文件中指定这   些属性的值；</p> <p>xxxxAutoConﬁgurartion：自动配置类； 给容器中添加组件</p> <p>xxxxProperties:封装配置文件中相关属性；</p> <h4 id="_3-10-2、细节"><a href="#_3-10-2、细节" class="header-anchor">#</a> 3.10.2、细节</h4> <p><strong>1</strong>、<strong>@Conditional</strong>派生注解（<strong>Spring</strong>注解版原生的**@Conditional**作用）</p> <p>作用：必须是@Conditional指定的条件成立，才给容器中添加组件，配置里面的所有内容才生效；</p> <table><thead><tr><th><strong>@Conditional</strong>扩展注解</th> <th>作用（判断是否满足当前指定条件）</th></tr></thead> <tbody><tr><td>@ConditionalOnJava</td> <td>系统的java版本是否符合要求</td></tr> <tr><td>@ConditionalOnBean</td> <td>容器中存在指定Bean；</td></tr> <tr><td>@ConditionalOnMissingBean</td> <td>容器中不存在指定Bean；</td></tr> <tr><td>@ConditionalOnExpression</td> <td>满足SpEL表达式指定</td></tr> <tr><td>@ConditionalOnClass</td> <td>系统中有指定的类</td></tr> <tr><td>@ConditionalOnMissingClass</td> <td>系统中没有指定的类</td></tr> <tr><td>@ConditionalOnSingleCandidate</td> <td>容器中只有一个指定的Bean，或者这个Bean是首选Bean</td></tr> <tr><td>@ConditionalOnProperty</td> <td>系统中指定的属性是否有指定的值</td></tr> <tr><td>@ConditionalOnResource</td> <td>类路径下是否存在指定资源文件</td></tr> <tr><td>@ConditionalOnWebApplication</td> <td>当前是web环境</td></tr> <tr><td>@ConditionalOnNotWebApplication</td> <td>当前不是web环境</td></tr> <tr><td>@ConditionalOnJndi</td> <td>JNDI存在指定项</td></tr></tbody></table> <p>自动配置类必须在一定的条件下才能生效； 我们怎么知道哪些自动配置类生效；</p> <p>我们可以通过启用   <strong>debug=true</strong>属性；来让控制台打印自动配置报告，这样我们就可以很方便的知道哪些自动配置类生效；</p> <div class="language- extra-class"><pre class="language-text"><code>=========================
AUTO‐CONFIGURATION REPORT
=========================
Positive matches:（自动配置类启用的）
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
DispatcherServletAutoConfiguration matched:
‐ @ConditionalOnClass found required class
'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find
unwanted class (OnClassCondition)
‐ @ConditionalOnWebApplication (required) found StandardServletEnvironment
(OnWebApplicationCondition)
Negative matches:（没有启动，没有匹配成功的自动配置类）
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
ActiveMQAutoConfiguration:
Did not match:
‐ @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory',
'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
AopAutoConfiguration:
Did not match:
‐ @ConditionalOnClass did not find required classes
'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
</code></pre></div><hr> <h1 id="三、日志"><a href="#三、日志" class="header-anchor">#</a> 三、日志</h1> <p>日志的详细介绍和logback的使用点击——&gt;<a href="https://www.lazyegg.net/JavaEgg/#/logging/Java-Logging" target="_blank" rel="noopener noreferrer">缕清各种Java Logging<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h2 id="_1、日志框架"><a href="#_1、日志框架" class="header-anchor">#</a> <strong>1</strong>、日志框架</h2> <p>Java大猿帅在很久很久以前，要开发一个大型系统的心路和发展历程；</p> <p>1、System.out.println(&quot;&quot;)；将关键数据打印在控制台；去掉？写在一个文件？</p> <p>2、框架来记录系统的一些运行时信息；日志框架 ； biglogging.jar；</p> <p>3、高大上的几个功能？异步模式？自动归档？xxxx？ biglogging-good.jar？</p> <p>4、将以前框架卸下来？换上新的框架，重新修改之前相关的API；biglogging-prefect.jar；</p> <p>5、JDBC---数据库驱动；</p> <p>6、写了一个统一的接口层；日志门面（日志的一个抽象层）；logging-abstract.jar； 给项目中导入具体的日志实现就行了；我们之前的日志框架都是实现的抽象层；</p> <p>市面上的日志框架；</p> <p>JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....</p> <table><thead><tr><th>日志门面 （日志的抽象层）</th> <th>日志实现</th></tr></thead> <tbody><tr><td>JCL（Jakarta  Commons Logging）、  SLF4j（Simple Logging Facade for Java）、  jboss-logging</td> <td>Log4j 、JUL（java.util.logging）、 Log4j2 <strong>Logback</strong></td></tr></tbody></table> <p>左边选一个门面（抽象层）、右边来选一个实现；我蒙着眼随便选两个，日志门面选： SLF4J，日志实现选：Logback（竟然和SpringBoot的设计者选的一样，英雄所见略同呀）；</p> <p>SpringBoot：底层是Spring框架，Spring框架默认是用JCL； <strong>SpringBoot</strong>选用 <strong>SLF4j</strong>和<strong>logback</strong>；</p> <h2 id="_2、slf4j使用"><a href="#_2、slf4j使用" class="header-anchor">#</a> 2、SLF4j使用</h2> <h3 id="_1、如何在系统中使用slf4j"><a href="#_1、如何在系统中使用slf4j" class="header-anchor">#</a> 1、如何在系统中使用<a href="https://www.slf4j.org" target="_blank" rel="noopener noreferrer">SLF4j<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></h3> <p>以后开发的时候，日志记录方法的调用，不应该来直接调用日志的实现类，而是调用日志抽象层里面的方法；  给系统里面导入slf4j的jar和 logback的实现jar</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>slf4j<span class="token punctuation">.</span></span><span class="token class-name">Logger</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>slf4j<span class="token punctuation">.</span></span><span class="token class-name">LoggerFactory</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloWorld</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token class-name">Logger</span> logger <span class="token operator">=</span> <span class="token class-name">LoggerFactory</span><span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span><span class="token class-name">HelloWorld</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  logger<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;Hello World&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>	
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>	
</code></pre></div><p>每一个日志的实现框架都有自己的配置文件。使用slf4j以后，<strong>配置文件还是做成日志实现框架自己本身的配置文  件；</strong></p> <h3 id="_2、遗留问题"><a href="#_2、遗留问题" class="header-anchor">#</a> <strong>2</strong>、遗留问题</h3> <p>SpringBoot（slf4j+logback）: Spring（commons-logging）、Hibernate（jboss-logging）、MyBatis、xxxx</p> <p>统一日志记录，即使是别的框架和我一起统一使用slf4j进行输出？</p> <p>如何让系统中所有的日志都统一到<strong>slf4j</strong>；</p> <p>1、将系统中其他日志框架先排除出去；</p> <p>2、用中间包来替换原有的日志框架；</p> <p>3、我们导入slf4j其他的实现</p> <h3 id="_3、springboot日志关系"><a href="#_3、springboot日志关系" class="header-anchor">#</a> <strong>3</strong>、SpringBoot日志关系</h3> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>SpringBoot使用它来做日志功能；</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐logging<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga25q0m4zaj20jr07mq3j.jpg" alt="springboot-log.png"></p> <p>总结：</p> <ol><li><p>SpringBoot底层也是使用slf4j+logback的方式进行日志记录</p></li> <li><p>SpringBoot也把其他的日志都替换成了slf4j；</p></li> <li><p>中间替换包</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">&quot;rawtypes&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">LogFactory</span> <span class="token punctuation">{</span>
<span class="token keyword">static</span> <span class="token class-name">String</span> UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J <span class="token operator">=</span>
<span class="token string">&quot;http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">static</span> <span class="token class-name">LogFactory</span> logFactory <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SLF4JLogFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>如果我们要引入其他框架？一定要把这个框架的默认日志依赖移除掉</p> <p>Spring框架用的是commons-logging；</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐core<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusions</span><span class="token punctuation">&gt;</span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
			<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>commons‐logging<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
			<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>commons‐logging<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
		<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusions</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div></li></ol> <p><strong>SpringBoot</strong>能自动适配所有的日志，而且底层使用<strong>slf4j+logback</strong>的方式记录日志，引入其他框架的时候，只需要把这个框架依赖的日志框架排除掉即可；</p> <h3 id="_4、日志使用"><a href="#_4、日志使用" class="header-anchor">#</a> <strong>4</strong>、日志使用</h3> <h4 id="_4-1、默认配置"><a href="#_4-1、默认配置" class="header-anchor">#</a> 4.1、默认配置</h4> <p>SpringBoot默认帮我们配置好了日志；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//记录器</span>
<span class="token class-name">Logger</span> logger <span class="token operator">=</span> <span class="token class-name">LoggerFactory</span><span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">contextLoads</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//System.out.println();</span>
    <span class="token comment">//日志的级别；</span>
    <span class="token comment">//由低到高 trace&lt;debug&lt;info&lt;warn&lt;error</span>
    <span class="token comment">//可以调整输出的日志级别；日志就只会在这个级别以以后的高级别生效</span>
    logger<span class="token punctuation">.</span><span class="token function">trace</span><span class="token punctuation">(</span><span class="token string">&quot;这是trace日志...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    logger<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">&quot;这是debug日志...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//SpringBoot默认给我们使用的是info级别的，没有指定级别的就用SpringBoot默认规定的级别；root</span>
    级别
    logger<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;这是info日志...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    logger<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">&quot;这是warn日志...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    logger<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">&quot;这是error日志...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre></div><div class="language- extra-class"><pre class="language-text"><code>日志输出格式：
%d表示日期时间，
%thread表示线程名，
%‐5level：级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符，否则按照句点分割。
%msg：日志消息，
%n是换行符
‐‐&gt;
%d{yyyy‐MM‐dd HH:mm:ss.SSS} [%thread] %‐5level %logger{50} ‐ %msg%n
</code></pre></div><p>SpringBoot修改日志的默认配置</p> <div class="language-properties extra-class"><pre class="language-properties"><code><span class="token attr-name">logging.level.cn.starfish</span><span class="token punctuation">=</span><span class="token attr-value">trace</span>
<span class="token comment">#logging.path=</span>
<span class="token comment"># 不指定路径在当前项目下生成springboot.log日志</span>
<span class="token comment"># 可以指定完整的路径；</span>
<span class="token comment">#logging.file=G:/springboot.log</span>
<span class="token comment"># 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹；使用 spring.log 作为默认文件</span>
<span class="token attr-name">logging.path</span><span class="token punctuation">=</span><span class="token attr-value">/spring/log</span>
<span class="token comment"># 在控制台输出的日志的格式</span>
<span class="token attr-name">logging.pattern.console</span><span class="token punctuation">=</span><span class="token attr-value">%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n</span>
<span class="token comment"># 指定文件中日志输出的格式</span>
<span class="token attr-name">logging.pattern.file</span><span class="token punctuation">=</span><span class="token attr-value">%d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n</span>
</code></pre></div><table><thead><tr><th><strong>logging.ﬁle</strong></th> <th><strong>logging.path</strong></th> <th><strong>Example</strong></th> <th><strong>Description</strong></th></tr></thead> <tbody><tr><td>(none)</td> <td>(none)</td> <td></td> <td>只在控制台输出</td></tr> <tr><td>指定文件名</td> <td>(none)</td> <td>my.log</td> <td>输出日志到my.log文件</td></tr> <tr><td>(none)</td> <td>指定目录</td> <td>/var/log</td> <td>输出到指定目录的 spring.log 文件中</td></tr></tbody></table> <h4 id="_4-2、指定配置"><a href="#_4-2、指定配置" class="header-anchor">#</a> 4.2、指定配置</h4> <p>给类路径下放上每个日志框架自己的配置文件即可；SpringBoot就不使用他默认配置的了</p> <table><thead><tr><th>Logging System</th> <th>Customization</th></tr></thead> <tbody><tr><td>Logback</td> <td>logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy</td></tr> <tr><td>Log4j2</td> <td>log4j2-spring.xml or log4j2.xml</td></tr> <tr><td>JDK (Java Util Logging)</td> <td>logging.properties</td></tr></tbody></table> <p>logback.xml：直接就被日志框架识别了；</p> <p><strong>logback-spring.xml</strong>：日志框架就不直接加载日志的配置项，由SpringBoot解析日志配置，可以使用SpringBoot</p> <p>的高级Proﬁle功能</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>staging<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span> <span class="token attr-name">configuration</span> <span class="token attr-name">to</span> <span class="token attr-name">be</span> <span class="token attr-name">enabled</span> <span class="token attr-name">when</span> <span class="token attr-name">the</span> <span class="token attr-name">&quot;staging&quot;</span> <span class="token attr-name">profile</span> <span class="token attr-name">is</span> <span class="token attr-name">active</span> <span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
可以指定某段配置只在某个环境下生效
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>如：</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>stdout<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.core.ConsoleAppender<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span>
   <span class="token attr-name">日志输出格式：</span>
   <span class="token attr-name">%d表示日期时间，</span>
   <span class="token attr-name">%thread表示线程名，</span>
   <span class="token attr-name">%‐5level：级别从左显示5个字符宽度</span>
   <span class="token attr-name">%logger{50}</span> <span class="token attr-name">表示logger名字最长50个字符，否则按照句点分割。</span>
   <span class="token attr-name">%msg：日志消息，</span>
   <span class="token attr-name">%n是换行符</span>
<span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>layout</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.classic.PatternLayout<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>dev<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pattern</span><span class="token punctuation">&gt;</span></span>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐&gt; [%thread] ‐‐‐&gt; %‐5level
%logger{50} ‐ %msg%n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pattern</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>!dev<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pattern</span><span class="token punctuation">&gt;</span></span>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level
%logger{50} ‐ %msg%n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pattern</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>layout</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>appender</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>如果使用logback.xml作为日志配置文件，还要使用proﬁle功能，会有以下错误</p> <div class="language-xml extra-class"><pre class="language-xml"><code>no applicable action for [springProfile]
</code></pre></div><h3 id="_5、切换日志框架"><a href="#_5、切换日志框架" class="header-anchor">#</a> <strong>5</strong>、切换日志框架</h3> <p>可以按照slf4j的日志适配图，进行相关的切换；</p> <p>slf4j+log4j的方式；</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusions</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>logback‐classic<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>ch.qos.logback<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>log4j‐over‐slf4j<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.slf4j<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusions</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.slf4j<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>slf4j‐log4j12<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>切换为log4j2</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusions</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐logging<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusions</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐log4j2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><hr> <h1 id="四、web开发"><a href="#四、web开发" class="header-anchor">#</a> 四、Web开发</h1> <h2 id="_1、使用springboot"><a href="#_1、使用springboot" class="header-anchor">#</a> 1、使用SpringBoot</h2> <p><strong>1</strong>）、创建<strong>SpringBoot</strong>应用，选中我们需要的模块；</p> <p><strong>2</strong>）、<strong>SpringBoot</strong>已经默认将这些场景配置好了，只需要在配置文件中指定少量配置就可以运行起来</p> <p><strong>3</strong>）、自己编写业务代码；</p> <h2 id="_2、springboot对静态资源的映射规则"><a href="#_2、springboot对静态资源的映射规则" class="header-anchor">#</a> <strong>2</strong>、SpringBoot对静态资源的映射规则；</h2> <p>一层一层的剥开SpringBoot到ResourceProperties，可以看到加载resource的路径顺序，以及属性的一些操作链（SpringBoot1.xx的版本是继承了ResourceLoaderAware，2.xx和1.xx的变化还挺大饿）。</p> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga0vgp4jfuj213f0jcn4z.jpg" alt="resource-properties.png"></p> <ul><li><p>所有 /webjars/** ，都去 classpath:/META-INF/resources/webjars/ 找资源；</p> <p><a href="http://www.webjars.org/" target="_blank" rel="noopener noreferrer">webjars<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>：以jar包的方式引入静态资源；</p> <p>localhost:8080/webjars/jquery/3.3.1/jquery.js</p></li></ul> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐引入jquery‐webjar‐‐</span><span class="token punctuation">&gt;</span></span>在访问的时候只需要写webjars下面资源的名称即可
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.webjars<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>jquery<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>3.3.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li><p>&quot;/**&quot; 访问当前项目的任何资源，都去（静态资源的文件夹）找映射</p> <div class="language-xml extra-class"><pre class="language-xml"><code></code></pre></div></li></ul> <p>&quot;classpath:/META‐INF/resources/&quot;,
&quot;classpath:/resources/&quot;,
&quot;classpath:/static/&quot;,
&quot;classpath:/public/&quot;
&quot;/&quot;：当前项目的根路径</p> <div class="language- extra-class"><pre class="language-text"><code>
localhost:8080/abc === 去静态资源文件夹里面找abc

- 欢迎页； 静态资源文件夹下的所有index.html页面；被&quot;/**&quot;映射；

localhost:8080/ 找index页面

- 所有的 **/favicon.ico 都是在静态资源文件下找；



## **3**、模板引擎

常见的模板引擎：JSP、Velocity、Freemarker、Thymeleaf

![template.png](http://ww1.sinaimg.cn/large/9b9f09a9ly1ga268zn2bxj20hy08b0t0.jpg)

SpringBoot推荐的Thymeleaf； 语法更简单，功能更强大；

### 3.1、引入thymeleaf；

```xml
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring‐boot‐starter‐thymeleaf&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;!--切换thymeleaf版本--&gt;
&lt;properties&gt;
&lt;thymeleaf.version&gt;3.0.9.RELEASE&lt;/thymeleaf.version&gt;
&lt;!‐‐布局功能的支持程序 thymeleaf3主程序 layout2以上版本‐‐&gt;
&lt;!‐‐ thymeleaf2 layout1‐‐&gt;
&lt;thymeleaf‐layout‐dialect.version&gt;2.2.2&lt;/thymeleaf‐layout‐dialect.version&gt;
&lt;/properties&gt;
</code></pre></div><h3 id="_3-2、thymeleaf使用"><a href="#_3-2、thymeleaf使用" class="header-anchor">#</a> 3.2、Thymeleaf使用</h3> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.thymeleaf&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ThymeleafProperties</span> <span class="token punctuation">{</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Charset</span> DEFAULT_ENCODING <span class="token operator">=</span> <span class="token class-name">Charset</span><span class="token punctuation">.</span><span class="token function">forName</span><span class="token punctuation">(</span><span class="token string">&quot;UTF‐8&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">MimeType</span> DEFAULT_CONTENT_TYPE <span class="token operator">=</span> <span class="token class-name">MimeType</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token string">&quot;text/html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> DEFAULT_PREFIX <span class="token operator">=</span> <span class="token string">&quot;classpath:/templates/&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> DEFAULT_SUFFIX <span class="token operator">=</span> <span class="token string">&quot;.html&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p>只要我们把HTML页面放在classpath:/templates/，thymeleaf就能自动渲染；</p> <ol><li><p>导入thymeleaf的名称空间</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>th</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.thymeleaf.org<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div></li> <li><p>使用thymeleaf语法；</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>th</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.thymeleaf.org<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>UTF‐8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>Title<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span>成功！<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">!‐‐th:</span>text</span> <span class="token attr-name">将div里面的文本内容设置为</span> <span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${hello}<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>这是显示欢迎信息<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre></div></li></ol> <h3 id="_3-3、语法规则"><a href="#_3-3、语法规则" class="header-anchor">#</a> 3.3、语法规则</h3> <p>1）、th:text；改变当前元素里面的文本内容；</p> <p>​	     th：任意html属性；来替换原生属性的值</p> <p>2）、表达式</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token class-name">Simple</span> expressions<span class="token operator">:</span>（表达式语法）
<span class="token class-name">Variable</span> <span class="token class-name">Expressions</span><span class="token operator">:</span> $<span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span>：获取变量值；OGNL；
<span class="token number">1</span>）、获取对象的属性、调用方法
<span class="token number">2</span>）、使用内置的基本对象：
#ctx <span class="token operator">:</span> the context object<span class="token punctuation">.</span>
#vars<span class="token operator">:</span> the context variables<span class="token punctuation">.</span>
#locale <span class="token operator">:</span> the context locale<span class="token punctuation">.</span>
#request <span class="token operator">:</span> <span class="token punctuation">(</span>only in <span class="token class-name">Web</span> <span class="token class-name">Contexts</span><span class="token punctuation">)</span> the <span class="token class-name">HttpServletRequest</span> object<span class="token punctuation">.</span>
#response <span class="token operator">:</span> <span class="token punctuation">(</span>only in <span class="token class-name">Web</span> <span class="token class-name">Contexts</span><span class="token punctuation">)</span> the <span class="token class-name">HttpServletResponse</span> object<span class="token punctuation">.</span>
#session <span class="token operator">:</span> <span class="token punctuation">(</span>only in <span class="token class-name">Web</span> <span class="token class-name">Contexts</span><span class="token punctuation">)</span> the <span class="token class-name">HttpSession</span> object<span class="token punctuation">.</span>
#servletContext <span class="token operator">:</span> <span class="token punctuation">(</span>only in <span class="token class-name">Web</span> <span class="token class-name">Contexts</span><span class="token punctuation">)</span> the <span class="token class-name">ServletContext</span> object<span class="token punctuation">.</span>
$<span class="token punctuation">{</span>session<span class="token punctuation">.</span>foo<span class="token punctuation">}</span>
<span class="token number">3</span>）、内置的一些工具对象：
#execInfo <span class="token operator">:</span> information about the template being processed<span class="token punctuation">.</span>
#messages <span class="token operator">:</span> methods <span class="token keyword">for</span> obtaining externalized messages inside variables expressions<span class="token punctuation">,</span> in the
same way as they would be obtained using #<span class="token punctuation">{</span>…<span class="token punctuation">}</span> syntax<span class="token punctuation">.</span>
#uris <span class="token operator">:</span> methods <span class="token keyword">for</span> escaping parts of <span class="token class-name">URLs</span><span class="token operator">/</span><span class="token class-name">URIs</span>
#conversions <span class="token operator">:</span> methods <span class="token keyword">for</span> executing the configured conversion service <span class="token punctuation">(</span><span class="token keyword">if</span> any<span class="token punctuation">)</span><span class="token punctuation">.</span>
#dates <span class="token operator">:</span> methods <span class="token keyword">for</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span><span class="token class-name">Date</span> objects<span class="token operator">:</span> formatting<span class="token punctuation">,</span> component extraction<span class="token punctuation">,</span> etc<span class="token punctuation">.</span>
#calendars <span class="token operator">:</span> analogous <span class="token keyword">to</span> #dates <span class="token punctuation">,</span> but <span class="token keyword">for</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span><span class="token class-name">Calendar</span> objects<span class="token punctuation">.</span>
#numbers <span class="token operator">:</span> methods <span class="token keyword">for</span> formatting numeric objects<span class="token punctuation">.</span>
#strings <span class="token operator">:</span> methods <span class="token keyword">for</span> <span class="token class-name">String</span> objects<span class="token operator">:</span> contains<span class="token punctuation">,</span> startsWith<span class="token punctuation">,</span> prepending<span class="token operator">/</span>appending<span class="token punctuation">,</span> etc<span class="token punctuation">.</span>
#objects <span class="token operator">:</span> methods <span class="token keyword">for</span> objects in general<span class="token punctuation">.</span>
#bools <span class="token operator">:</span> methods <span class="token keyword">for</span> <span class="token keyword">boolean</span> evaluation<span class="token punctuation">.</span>
#arrays <span class="token operator">:</span> methods <span class="token keyword">for</span> arrays<span class="token punctuation">.</span>
#lists <span class="token operator">:</span> methods <span class="token keyword">for</span> lists<span class="token punctuation">.</span>
#sets <span class="token operator">:</span> methods <span class="token keyword">for</span> sets<span class="token punctuation">.</span>
#maps <span class="token operator">:</span> methods <span class="token keyword">for</span> maps<span class="token punctuation">.</span>
#aggregates <span class="token operator">:</span> methods <span class="token keyword">for</span> creating aggregates on arrays or collections<span class="token punctuation">.</span>
#ids <span class="token operator">:</span> methods <span class="token keyword">for</span> dealing <span class="token keyword">with</span> <span class="token namespace">id</span> attributes that might be repeated <span class="token punctuation">(</span><span class="token keyword">for</span> example<span class="token punctuation">,</span> as a
result of an iteration<span class="token punctuation">)</span><span class="token punctuation">.</span>
<span class="token class-name">Selection</span> <span class="token class-name">Variable</span> <span class="token class-name">Expressions</span><span class="token operator">:</span> <span class="token operator">*</span><span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span>：选择表达式：和$<span class="token punctuation">{</span><span class="token punctuation">}</span>在功能上是一样；
补充：配合 th<span class="token operator">:</span>object<span class="token operator">=</span>&quot;$<span class="token punctuation">{</span>session<span class="token punctuation">.</span>user<span class="token punctuation">}</span>：
<span class="token operator">&lt;</span>div th<span class="token operator">:</span>object<span class="token operator">=</span><span class="token string">&quot;${session.user}&quot;</span><span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>p<span class="token punctuation">&gt;</span></span><span class="token class-name">Name</span><span class="token operator">:</span> <span class="token operator">&lt;</span>span th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;*{firstName}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Sebastian</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span><span class="token punctuation">.</span>&lt;<span class="token operator">/</span>p<span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>p<span class="token punctuation">&gt;</span></span><span class="token class-name">Surname</span><span class="token operator">:</span> <span class="token operator">&lt;</span>span th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;*{lastName}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Pepper</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span><span class="token punctuation">.</span>&lt;<span class="token operator">/</span>p<span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>p<span class="token punctuation">&gt;</span></span><span class="token class-name">Nationality</span><span class="token operator">:</span> <span class="token operator">&lt;</span>span th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;*{nationality}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Saturn</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span><span class="token punctuation">.</span>&lt;<span class="token operator">/</span>p<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token class-name">Message</span> <span class="token class-name">Expressions</span><span class="token operator">:</span> #<span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span>：获取国际化内容
<span class="token class-name">Link</span> URL <span class="token class-name">Expressions</span><span class="token operator">:</span> @<span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span>：定义URL；
@<span class="token punctuation">{</span><span class="token operator">/</span>order<span class="token operator">/</span><span class="token function">process</span><span class="token punctuation">(</span>execId<span class="token operator">=</span>$<span class="token punctuation">{</span>execId<span class="token punctuation">}</span><span class="token punctuation">,</span>execType<span class="token operator">=</span><span class="token string">'FAST'</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
<span class="token class-name">Fragment</span> <span class="token class-name">Expressions</span><span class="token operator">:</span> <span class="token operator">~</span><span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span>：片段引用表达式
<span class="token operator">&lt;</span>div th<span class="token operator">:</span>insert<span class="token operator">=</span><span class="token string">&quot;~{commons :: main}&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>&lt;<span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token class-name">Literals</span>（字面量）
<span class="token class-name">Text</span> literals<span class="token operator">:</span> <span class="token string">'one text'</span> <span class="token punctuation">,</span> <span class="token string">'Another one!'</span> <span class="token punctuation">,</span>…
<span class="token class-name">Number</span> literals<span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">3.0</span> <span class="token punctuation">,</span> <span class="token number">12.3</span> <span class="token punctuation">,</span>…
<span class="token class-name">Boolean</span> literals<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token boolean">false</span>
<span class="token class-name">Null</span> literal<span class="token operator">:</span> <span class="token keyword">null</span>
<span class="token class-name">Literal</span> tokens<span class="token operator">:</span> one <span class="token punctuation">,</span> sometext <span class="token punctuation">,</span> main <span class="token punctuation">,</span>…
<span class="token class-name">Text</span> operations<span class="token operator">:</span>（文本操作）
<span class="token class-name">String</span> concatenation<span class="token operator">:</span> <span class="token operator">+</span>
<span class="token class-name">Literal</span> substitutions<span class="token operator">:</span> <span class="token operator">|</span><span class="token class-name">The</span> name is $<span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token operator">|</span>
<span class="token class-name">Arithmetic</span> operations<span class="token operator">:</span>（数学运算）
<span class="token class-name">Binary</span> operators<span class="token operator">:</span> <span class="token operator">+</span> <span class="token punctuation">,</span> ‐ <span class="token punctuation">,</span> <span class="token operator">*</span> <span class="token punctuation">,</span> <span class="token operator">/</span> <span class="token punctuation">,</span> <span class="token operator">%</span>
</code></pre></div><h2 id="_4、springmvc自动配置"><a href="#_4、springmvc自动配置" class="header-anchor">#</a> 4、SpringMVC自动配置</h2> <h3 id="_4-1、spring-mvc-auto-configuration"><a href="#_4-1、spring-mvc-auto-configuration" class="header-anchor">#</a> 4.1、Spring MVC auto-conﬁguration</h3> <p>Spring Boot 自动配置好了SpringMVC</p> <p>以下是SpringBoot对SpringMVC的默认配置:（<strong>WebMvcAutoConﬁguration</strong>）</p> <ul><li>Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
<ul><li>自动配置了ViewResolver（视图解析器：根据方法的返回值得到视图对象（View），视图对象决定如何 渲染（转发？重定向？））</li> <li>ContentNegotiatingViewResolver：组合所有的视图解析器的；</li> <li>如何定制：我们可以自己给容器中添加一个视图解析器；自动的将其组合进来；</li></ul></li> <li>Support for serving static resources, including support for WebJars (see below).静态资源文件夹路 径,webjars</li> <li>Static index.html support. 静态首页访问</li> <li>Custom Favicon support (see below). favicon.ico</li> <li>自动注册了 of Converter , GenericConverter , Formatter beans. Converter：转换器； public String hello(User user)：类型转换使用Converter Formatter 格式化器； 2017.12.17===Date；</li></ul> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@ConditionalOnProperty</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.mvc&quot;</span><span class="token punctuation">,</span> name <span class="token operator">=</span> <span class="token string">&quot;date‐format&quot;</span><span class="token punctuation">)</span><span class="token comment">//在文件中配置日期格</span>
式化的规则
<span class="token keyword">public</span> <span class="token class-name">Formatter</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Date</span><span class="token punctuation">&gt;</span></span> <span class="token function">dateFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">DateFormatter</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties<span class="token punctuation">.</span><span class="token function">getDateFormat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//日期格式化组件</span>
<span class="token punctuation">}</span>
</code></pre></div><p>自己添加的格式化器转换器，我们只需要放在容器中即可</p> <ul><li>Support for HttpMessageConverters (see below).
<ul><li>HttpMessageConverter：SpringMVC用来转换Http请求和响应的；User---Json</li> <li>HttpMessageConverters 是从容器中确定；获取所有的HttpMessageConverter； 自己给容器中添加HttpMessageConverter，只需要将自己的组件注册容器中 （@Bean,@Component）</li></ul></li> <li>Automatic registration of MessageCodesResolver (see below).定义错误代码生成规则</li> <li>Automatic use of a ConfigurableWebBindingInitializer bean (see below). 我们可以配置一个ConfigurableWebBindingInitializer来替换默认的；（添加到容器）</li></ul> <h3 id="_4-2、扩展springmvc"><a href="#_4-2、扩展springmvc" class="header-anchor">#</a> 4.2、扩展SpringMVC</h3> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">mvc:</span>view‐controller</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/hello<span class="token punctuation">&quot;</span></span> <span class="token attr-name">view‐name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>success<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">mvc:</span>interceptors</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">mvc:</span>interceptor</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">mvc:</span>mapping</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/hello<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">mvc:</span>interceptor</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">mvc:</span>interceptors</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>编写一个配置类（@Conﬁguration），是WebMvcConﬁgurerAdapter类型；不能标注@EnableWebMvc;</p> <p>既保留了所有的自动配置，也能用我们扩展的配置；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能</span>
<span class="token annotation punctuation">@Configuration</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyMvcConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebMvcConfigurerAdapter</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addViewControllers</span><span class="token punctuation">(</span><span class="token class-name">ViewControllerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// super.addViewControllers(registry);</span>
    <span class="token comment">//浏览器发送 /atguigu 请求来到 success</span>
    registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/atguigu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;success&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>原理：</p> <p>1）、WebMvcAutoConﬁguration是SpringMVC的自动配置类</p> <p>2）、在做其他自动配置时会导入；@Import(<strong>EnableWebMvcConﬁguration</strong>.class)</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">EnableWebMvcConfiguration</span> <span class="token keyword">extends</span> <span class="token class-name">DelegatingWebMvcConfiguration</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">WebMvcConfigurerComposite</span> configurers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebMvcConfigurerComposite</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//从容器中获取所有的WebMvcConfigurer</span>
    <span class="token annotation punctuation">@Autowired</span><span class="token punctuation">(</span>required <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setConfigurers</span><span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">&gt;</span></span> configurers<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>configurers<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>configurers<span class="token punctuation">.</span><span class="token function">addWebMvcConfigurers</span><span class="token punctuation">(</span>configurers<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//一个参考实现；将所有的WebMvcConfigurer相关配置都来一起调用；</span>
                    <span class="token annotation punctuation">@Override</span>
    <span class="token comment">// public void addViewControllers(ViewControllerRegistry registry) {</span>
    <span class="token comment">// for (WebMvcConfigurer delegate : this.delegates) {</span>
    <span class="token comment">// delegate.addViewControllers(registry);</span>
    <span class="token comment">// }</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>3）、容器中所有的WebMvcConﬁgurer都会一起起作用；</p> <p>4）、我们的配置类也会被调用；</p> <p>效果：SpringMVC的自动配置和我们的扩展配置都会起作用；</p> <h3 id="_4-3、全面接管springmvc"><a href="#_4-3、全面接管springmvc" class="header-anchor">#</a> 4.3、全面接管SpringMVC；</h3> <p>SpringBoot对SpringMVC的自动配置不需要了，所有都是我们自己配置；所有的SpringMVC的自动配置都失效了 我们需要在配置类中添加@EnableWebMvc即可；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能</span>
<span class="token annotation punctuation">@EnableWebMvc</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyMvcConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebMvcConfigurerAdapter</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addViewControllers</span><span class="token punctuation">(</span><span class="token class-name">ViewControllerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// super.addViewControllers(registry);</span>
    <span class="token comment">//浏览器发送 /atguigu 请求来到 success</span>
    registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/atguigu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;success&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>原理：</p> <p>为什么@EnableWebMvc自动配置就失效了；</p> <p>1）@EnableWebMvc的核心</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token class-name">DelegatingWebMvcConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">EnableWebMvc</span> <span class="token punctuation">{</span>
</code></pre></div><p>2）、</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DelegatingWebMvcConfiguration</span> <span class="token keyword">extends</span> <span class="token class-name">WebMvcConfigurationSupport</span> <span class="token punctuation">{</span>

</code></pre></div><p>3）、</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ConditionalOnWebApplication</span>
<span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">Servlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">DispatcherServlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>
<span class="token class-name">WebMvcConfigurerAdapter</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">//容器中没有这个组件的时候，这个自动配置类才生效</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span><span class="token class-name">WebMvcConfigurationSupport</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@AutoConfigureOrder</span><span class="token punctuation">(</span><span class="token class-name">Ordered</span><span class="token punctuation">.</span>HIGHEST_PRECEDENCE <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@AutoConfigureAfter</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">DispatcherServletAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>
<span class="token class-name">ValidationAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">WebMvcAutoConfiguration</span> <span class="token punctuation">{</span>
</code></pre></div><p>4）、@EnableWebMvc将WebMvcConﬁgurationSupport组件导入进来；</p> <p>5）、导入的WebMvcConﬁgurationSupport只是SpringMVC最基本的功能；</p> <h2 id="_5、如何修改springboot的默认配置"><a href="#_5、如何修改springboot的默认配置" class="header-anchor">#</a> 5、如何修改SpringBoot的默认配置</h2> <p>模式：</p> <p>1）、SpringBoot在自动配置很多组件的时候，先看容器中有没有用户自己配置的（@Bean、@Component）如   果有就用用户配置的，如果没有，才自动配置；如果有些组件可以有多个（ViewResolver）将用户配置的和自己默 认的组合起来；</p> <p>2）、在SpringBoot中会有非常多的xxxConﬁgurer帮助我们进行扩展配置</p> <p>3）、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置</p> <h2 id="_6、restfulcrud"><a href="#_6、restfulcrud" class="header-anchor">#</a> 6、RestfulCRUD</h2> <h4 id="_1-、默认访问首页"><a href="#_1-、默认访问首页" class="header-anchor">#</a> 1）、默认访问首页</h4> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能</span>
<span class="token comment">//@EnableWebMvc 不要接管SpringMVC</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyMvcConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebMvcConfigurerAdapter</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addViewControllers</span><span class="token punctuation">(</span><span class="token class-name">ViewControllerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// super.addViewControllers(registry);</span>
        <span class="token comment">//浏览器发送 /atguigu 请求来到 success</span>
        registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/atguigu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;success&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//所有的WebMvcConfigurerAdapter组件都会一起起作用</span>
    <span class="token annotation punctuation">@Bean</span> <span class="token comment">//将组件注册在容器</span>
    <span class="token keyword">public</span> <span class="token class-name">WebMvcConfigurerAdapter</span> <span class="token function">webMvcConfigurerAdapter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">WebMvcConfigurerAdapter</span> adapter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebMvcConfigurerAdapter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addViewControllers</span><span class="token punctuation">(</span><span class="token class-name">ViewControllerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;login&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;login&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> adapter<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="_2-、国际化"><a href="#_2-、国际化" class="header-anchor">#</a> 2）、国际化</h4> <ul><li>编写国际化配置文件；</li> <li>使用ResourceBundleMessageSource管理国际化资源文件</li> <li>在页面使用fmt:message取出国际化内容</li></ul> <p>步骤：</p> <p>a、编写国际化配置文件，抽取页面需要显示的国际化消息</p> <p>b、SpringBoot自动配置好了管理国际化资源文件的组件；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.messages&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MessageSourceAutoConfiguration</span> <span class="token punctuation">{</span>
    <span class="token comment">/**
     * Comma‐separated list of basenames (essentially a fully‐qualified classpath
     * location), each following the ResourceBundle convention with relaxed support for
     * slash based locations. If it doesn't contain a package qualifier (such as
     * &quot;org.mypackage&quot;), it will be resolved from the classpath root.
     */</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> basename <span class="token operator">=</span> <span class="token string">&quot;messages&quot;</span><span class="token punctuation">;</span>
    <span class="token comment">//我们的配置文件可以直接放在类路径下叫messages.properties；</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">MessageSource</span> <span class="token function">messageSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">ResourceBundleMessageSource</span> messageSource <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ResourceBundleMessageSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>basename<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//设置国际化资源文件的基础名（去掉语言国家代码的）</span>
            messageSource<span class="token punctuation">.</span><span class="token function">setBasenames</span><span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">commaDelimitedListToStringArray</span><span class="token punctuation">(</span>
                    <span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">trimAllWhitespace</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>basename<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>encoding <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            messageSource<span class="token punctuation">.</span><span class="token function">setDefaultEncoding</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>encoding<span class="token punctuation">.</span><span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        messageSource<span class="token punctuation">.</span><span class="token function">setFallbackToSystemLocale</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>fallbackToSystemLocale<span class="token punctuation">)</span><span class="token punctuation">;</span>
        messageSource<span class="token punctuation">.</span><span class="token function">setCacheSeconds</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>cacheSeconds<span class="token punctuation">)</span><span class="token punctuation">;</span>
        messageSource<span class="token punctuation">.</span><span class="token function">setAlwaysUseMessageFormat</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>alwaysUseMessageFormat<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> messageSource<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code> <span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix  <span class="token operator">=</span>  <span class="token string">&quot;spring.messages&quot;</span><span class="token punctuation">)</span>  
<span class="token keyword">public</span>  <span class="token keyword">class</span>  <span class="token class-name">MessageSourceAutoConfiguration</span>  <span class="token punctuation">{</span> <span class="token number">3</span>

           <span class="token keyword">private</span>  <span class="token class-name">String</span>  basename  <span class="token operator">=</span>  <span class="token string">&quot;messages&quot;</span><span class="token punctuation">;</span>
           <span class="token comment">//我们的配置文件可以直接放在类路径下叫messages.properties； 12</span>

           <span class="token annotation punctuation">@Bean</span>
           <span class="token keyword">public</span>  <span class="token class-name">MessageSource</span>  <span class="token function">messageSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
                   <span class="token class-name">ResourceBundleMessageSource</span>  messageSource  <span class="token operator">=</span>  <span class="token keyword">new</span>  <span class="token class-name">ResourceBundleMessageSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                   <span class="token keyword">if</span>  <span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>basename<span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
                            <span class="token comment">//设置国际化资源文件的基础名（去掉语言国家代码的）                           messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(</span>

                   <span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">trimAllWhitespace</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>basename<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token number">20</span>     <span class="token punctuation">}</span>

                   <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>encoding <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>

                   messageSource<span class="token punctuation">.</span><span class="token function">setDefaultEncoding</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>encoding<span class="token punctuation">.</span><span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token number">23</span>    <span class="token punctuation">}</span>

                   messageSource<span class="token punctuation">.</span><span class="token function">setFallbackToSystemLocale</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>fallbackToSystemLocale<span class="token punctuation">)</span><span class="token punctuation">;</span>

                   messageSource<span class="token punctuation">.</span><span class="token function">setCacheSeconds</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>cacheSeconds<span class="token punctuation">)</span><span class="token punctuation">;</span>

                   messageSource<span class="token punctuation">.</span><span class="token function">setAlwaysUseMessageFormat</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>alwaysUseMessageFormat<span class="token punctuation">)</span><span class="token punctuation">;</span>

           <span class="token keyword">return</span>  messageSource<span class="token punctuation">;</span> <span class="token number">28</span>        <span class="token punctuation">}</span>
</code></pre></div><p>c、去页面获取国际化的值；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token operator">&lt;</span><span class="token operator">!</span>DOCTYPE html<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>html lang<span class="token operator">=</span><span class="token string">&quot;en&quot;</span> xmlns<span class="token operator">:</span>th<span class="token operator">=</span><span class="token string">&quot;http://www.thymeleaf.org&quot;</span><span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>head<span class="token punctuation">&gt;</span></span>
<span class="token operator">&lt;</span>meta http‐equiv<span class="token operator">=</span><span class="token string">&quot;Content‐Type&quot;</span> content<span class="token operator">=</span><span class="token string">&quot;text/html; charset=UTF‐8&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>meta name<span class="token operator">=</span><span class="token string">&quot;viewport&quot;</span> content<span class="token operator">=</span>&quot;width<span class="token operator">=</span>device‐width<span class="token punctuation">,</span> initial‐scale<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span> shrink‐<span class="token keyword">to</span>‐
fit<span class="token operator">=</span>no&quot;<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>meta name<span class="token operator">=</span><span class="token string">&quot;description&quot;</span> content<span class="token operator">=</span><span class="token string">&quot;&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>meta name<span class="token operator">=</span><span class="token string">&quot;author&quot;</span> content<span class="token operator">=</span><span class="token string">&quot;&quot;</span><span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>title<span class="token punctuation">&gt;</span></span><span class="token class-name">Signin</span> <span class="token class-name">Template</span> <span class="token keyword">for</span> <span class="token class-name">Bootstrap</span><span class="token operator">&lt;</span><span class="token operator">/</span>title<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">!</span>‐‐ <span class="token class-name">Bootstrap</span> core CSS ‐‐<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>link href<span class="token operator">=</span><span class="token string">&quot;asserts/css/bootstrap.min.css&quot;</span>
th<span class="token operator">:</span>href<span class="token operator">=</span><span class="token string">&quot;@{/webjars/bootstrap/4.0.0/css/bootstrap.css}&quot;</span> rel<span class="token operator">=</span><span class="token string">&quot;stylesheet&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">!</span>‐‐ <span class="token class-name">Custom</span> styles <span class="token keyword">for</span> <span class="token keyword">this</span> template ‐‐<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>link href<span class="token operator">=</span><span class="token string">&quot;asserts/css/signin.css&quot;</span> th<span class="token operator">:</span>href<span class="token operator">=</span><span class="token string">&quot;@{/asserts/css/signin.css}&quot;</span>
rel<span class="token operator">=</span><span class="token string">&quot;stylesheet&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>head<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>body <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;text‐center&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>form <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;form‐signin&quot;</span> action<span class="token operator">=</span><span class="token string">&quot;dashboard.html&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>img <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;mb‐4&quot;</span> th<span class="token operator">:</span>src<span class="token operator">=</span><span class="token string">&quot;@{/asserts/img/bootstrap‐solid.svg}&quot;</span>
src<span class="token operator">=</span><span class="token string">&quot;asserts/img/bootstrap‐solid.svg&quot;</span> alt<span class="token operator">=</span><span class="token string">&quot;&quot;</span> width<span class="token operator">=</span><span class="token string">&quot;72&quot;</span> height<span class="token operator">=</span><span class="token string">&quot;72&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>h1 <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;h3 mb‐3 font‐weight‐normal&quot;</span> th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;#{login.tip}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Please</span> sign
in<span class="token operator">&lt;</span><span class="token operator">/</span>h1<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>label <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;sr‐only&quot;</span> th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;#{login.username}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Username</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>input type<span class="token operator">=</span><span class="token string">&quot;text&quot;</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;form‐control&quot;</span> placeholder<span class="token operator">=</span><span class="token string">&quot;Username&quot;</span> th<span class="token operator">:</span>placeholder<span class="token operator">=</span>&quot;#
<span class="token punctuation">{</span>login<span class="token punctuation">.</span>username<span class="token punctuation">}</span><span class="token string">&quot; required=&quot;</span><span class="token string">&quot; autofocus=&quot;</span>&quot;<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>label <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;sr‐only&quot;</span> th<span class="token operator">:</span>text<span class="token operator">=</span><span class="token string">&quot;#{login.password}&quot;</span><span class="token operator">&gt;</span><span class="token class-name">Password</span><span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>input type<span class="token operator">=</span><span class="token string">&quot;password&quot;</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;form‐control&quot;</span> placeholder<span class="token operator">=</span><span class="token string">&quot;Password&quot;</span>
th<span class="token operator">:</span>placeholder<span class="token operator">=</span><span class="token string">&quot;#{login.password}&quot;</span> required<span class="token operator">=</span><span class="token string">&quot;&quot;</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;checkbox mb‐3&quot;</span><span class="token operator">&gt;</span>
<span class="token generics"><span class="token punctuation">&lt;</span>label<span class="token punctuation">&gt;</span></span>
<span class="token operator">&lt;</span>input type<span class="token operator">=</span><span class="token string">&quot;checkbox&quot;</span> value<span class="token operator">=</span><span class="token string">&quot;remember‐me&quot;</span><span class="token operator">/</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>#<span class="token punctuation">{</span>login<span class="token punctuation">.</span>remember<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>label<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>button <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;btn btn‐lg btn‐primary btn‐block&quot;</span> type<span class="token operator">=</span><span class="token string">&quot;submit&quot;</span> th<span class="token operator">:</span>text<span class="token operator">=</span>&quot;#
<span class="token punctuation">{</span>login<span class="token punctuation">.</span>btn<span class="token punctuation">}</span>&quot;<span class="token operator">&gt;</span><span class="token class-name">Sign</span> in<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>p <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;mt‐5 mb‐3 text‐muted&quot;</span><span class="token operator">&gt;</span>© <span class="token number">2017</span>‐<span class="token number">2018</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>a <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;btn btn‐sm&quot;</span><span class="token operator">&gt;</span>中文<span class="token operator">&lt;</span><span class="token operator">/</span>a<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>a <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;btn btn‐sm&quot;</span><span class="token operator">&gt;</span><span class="token class-name">English</span><span class="token operator">&lt;</span><span class="token operator">/</span>a<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>form<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>body<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>html<span class="token operator">&gt;</span>
</code></pre></div><p>效果：根据浏览器语言设置的信息切换了国际化；</p> <p>原理：</p> <p>国际化Locale（区域信息对象）；LocaleResolver（获取区域信息对象）；默认的就是根据请求头带来的区域信息获取Locale进行国际化</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span>
<span class="token annotation punctuation">@ConditionalOnProperty</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.mvc&quot;</span><span class="token punctuation">,</span> name <span class="token operator">=</span> <span class="token string">&quot;locale&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">LocaleResolver</span> <span class="token function">localeResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties
	<span class="token punctuation">.</span><span class="token function">getLocaleResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token class-name">WebMvcProperties</span><span class="token punctuation">.</span><span class="token class-name">LocaleResolver</span><span class="token punctuation">.</span>FIXED<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">FixedLocaleResolver</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties<span class="token punctuation">.</span><span class="token function">getLocale</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token class-name">AcceptHeaderLocaleResolver</span> localeResolver <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AcceptHeaderLocaleResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	localeResolver<span class="token punctuation">.</span><span class="token function">setDefaultLocale</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties<span class="token punctuation">.</span><span class="token function">getLocale</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> localeResolver<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>d、点击链接切换国际化</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
 * 可以在连接上携带区域信息
 */</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyLocaleResolver</span> <span class="token keyword">implements</span> <span class="token class-name">LocaleResolver</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">Locale</span> <span class="token function">resolveLocale</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">String</span> l <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">&quot;l&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Locale</span> locale <span class="token operator">=</span> <span class="token class-name">Locale</span><span class="token punctuation">.</span><span class="token function">getDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>l<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> split <span class="token operator">=</span> l<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&quot;_&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            locale <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Locale</span><span class="token punctuation">(</span>split<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>split<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> locale<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setLocale</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">Locale</span>
            locale<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">LocaleResolver</span> <span class="token function">localeResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">MyLocaleResolver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="_3-、登陆"><a href="#_3-、登陆" class="header-anchor">#</a> 3）、登陆</h4> <p>开发期间模板引擎页面修改以后，要实时生效</p> <p>​	a、禁用模板引擎的缓存</p> <div class="language-properties extra-class"><pre class="language-properties"><code><span class="token comment"># 禁用缓存</span>
<span class="token attr-name">spring.thymeleaf.cache</span><span class="token punctuation">=</span><span class="token attr-value">false</span>
</code></pre></div><p>​	b、页面修改完成以后ctrl+f9：重新编译； 登陆错误消息的显示</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">=&quot;</span><span class="token attr-value"><span class="token property">color</span><span class="token punctuation">:</span> red</span><span class="token punctuation">&quot;</span></span> <span class="token attr-name"><span class="token namespace">th:</span>text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${msg}<span class="token punctuation">&quot;</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${not #strings.isEmpty(msg)}<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h4 id="_4-、拦截器进行登陆检查"><a href="#_4-、拦截器进行登陆检查" class="header-anchor">#</a> 4）、拦截器进行登陆检查</h4> <p>拦截器</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
 * 登陆检查，
 */</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginHandlerInterceptor</span> <span class="token keyword">implements</span> <span class="token class-name">HandlerInterceptor</span> <span class="token punctuation">{</span>
    <span class="token comment">//目标方法执行之前</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">preHandle</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span>
                             <span class="token class-name">Object</span> handler<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
        <span class="token class-name">Object</span> user <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">&quot;loginUser&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>user <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token comment">//未登陆，返回登陆页面</span>
            request<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&quot;msg&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;没有权限请先登陆&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            request<span class="token punctuation">.</span><span class="token function">getRequestDispatcher</span><span class="token punctuation">(</span><span class="token string">&quot;/index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forward</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span>
<span class="token comment">//已登陆，放行请求</span>
            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">postHandle</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">Object</span>
            handler<span class="token punctuation">,</span> <span class="token class-name">ModelAndView</span> modelAndView<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">afterCompletion</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span>
                                <span class="token class-name">Object</span> handler<span class="token punctuation">,</span> <span class="token class-name">Exception</span> ex<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>

</code></pre></div><p>注册拦截器</p> <div class="language-java extra-class"><pre class="language-java"><code> <span class="token comment">//所有的WebMvcConfigurerAdapter组件都会一起起作用</span>
   <span class="token annotation punctuation">@Bean</span> <span class="token comment">//将组件注册在容器</span>
   <span class="token keyword">public</span> <span class="token class-name">WebMvcConfigurerAdapter</span> <span class="token function">webMvcConfigurerAdapter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
       <span class="token class-name">WebMvcConfigurerAdapter</span> adapter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebMvcConfigurerAdapter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
           <span class="token annotation punctuation">@Override</span>
           <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addViewControllers</span><span class="token punctuation">(</span><span class="token class-name">ViewControllerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
               registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;login&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
               registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;login&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
               registry<span class="token punctuation">.</span><span class="token function">addViewController</span><span class="token punctuation">(</span><span class="token string">&quot;/main.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setViewName</span><span class="token punctuation">(</span><span class="token string">&quot;dashboard&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
           <span class="token punctuation">}</span>
           <span class="token comment">//注册拦截器</span>
           <span class="token annotation punctuation">@Override</span>
           <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addInterceptors</span><span class="token punctuation">(</span><span class="token class-name">InterceptorRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//super.addInterceptors(registry);</span>
<span class="token comment">//静态资源； *.css , *.js</span>
<span class="token comment">//SpringBoot已经做好了静态资源映射</span>
               registry<span class="token punctuation">.</span><span class="token function">addInterceptor</span><span class="token punctuation">(</span><span class="token keyword">new</span>
                       <span class="token class-name">LoginHandlerInterceptor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addPathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/**&quot;</span><span class="token punctuation">)</span>
                       <span class="token punctuation">.</span><span class="token function">excludePathPatterns</span><span class="token punctuation">(</span><span class="token string">&quot;/index.html&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;/user/login&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
           <span class="token punctuation">}</span>
       <span class="token punctuation">}</span><span class="token punctuation">;</span>
       <span class="token keyword">return</span> adapter<span class="token punctuation">;</span>
   <span class="token punctuation">}</span>
</code></pre></div><h4 id="_5-、crud-员工列表"><a href="#_5-、crud-员工列表" class="header-anchor">#</a> 5）、CRUD-员工列表</h4> <p>实验要求：</p> <p>a、RestfulCRUD：CRUD满足Rest风格；</p> <p>URI： /资源名称/资源标识 HTTP请求方式区分对资源CRUD操作</p> <table><thead><tr><th></th> <th>普通<strong>CRUD</strong>（<strong>uri</strong>来区分操作）</th> <th><strong>RestfulCRUD</strong></th></tr></thead> <tbody><tr><td>查询</td> <td>getEmp</td> <td>emp---GET</td></tr> <tr><td>添加</td> <td>addEmp?xxx</td> <td>emp---POST</td></tr> <tr><td>修改</td> <td>updateEmp?id=xxx&amp;xxx=xx</td> <td>emp/{id}---PUT</td></tr> <tr><td>删除</td> <td>deleteEmp?id=1</td> <td>emp/{id}---DELETE</td></tr></tbody></table> <p>b、实验的请求架构;</p> <table><thead><tr><th>实验功能</th> <th>请求<strong>URI</strong></th> <th>请求方式</th></tr></thead> <tbody><tr><td>查询所有员工</td> <td>emps</td> <td>GET</td></tr> <tr><td>查询某个员工(来到修改页面)</td> <td>emp/1</td> <td>GET</td></tr> <tr><td>来到添加页面</td> <td>emp</td> <td>GET</td></tr> <tr><td>添加员工</td> <td>emp</td> <td>POST</td></tr> <tr><td>来到修改页面（查出员工进行信息回显）</td> <td>emp/1</td> <td>GET</td></tr> <tr><td>修改员工</td> <td>emp</td> <td>PUT</td></tr> <tr><td>删除员工</td> <td>emp/1</td> <td>DELETE</td></tr></tbody></table> <p>c、员工列表：</p> <p><strong>thymeleaf</strong>公共页面元素抽取</p> <div class="language-html extra-class"><pre class="language-html"><code>1、抽取公共片段
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>fragment</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>copy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token entity named-entity" title="&amp;copy;">&amp;copy;</span> 2011 The Good Thymes Virtual Grocery
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
2、引入公共片段
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>insert</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>~{footer :: copy}<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
~{templatename::selector}：模板名::选择器
~{templatename::fragmentname}:模板名::片段名
3、默认效果：
insert的公共片段在div标签中
如果使用th:insert等属性进行引入，可以不用写~{}：
行内写法可以加上：[[~{}]];[(~{})]； 
</code></pre></div><p>三种引入公共片段的th属性：</p> <p><strong>th:insert</strong>：将公共片段整个插入到声明引入的元素中</p> <p><strong>th:replace</strong>：将声明引入的元素替换为公共片段</p> <p><strong>th:include</strong>：将被引入的片段的内容包含进这个标签中</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>footer</span> <span class="token attr-name"><span class="token namespace">th:</span>fragment</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>copy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token entity named-entity" title="&amp;copy;">&amp;copy;</span> 2011 The Good Thymes Virtual Grocery
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>footer</span><span class="token punctuation">&gt;</span></span>
引入方式
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>insert</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer :: copy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
引入片段的时候传入参数：
6）、CRUD-员工添加
添加页面
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>replace</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer :: copy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name"><span class="token namespace">th:</span>include</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer :: copy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
效果
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>footer</span><span class="token punctuation">&gt;</span></span>
<span class="token entity named-entity" title="&amp;copy;">&amp;copy;</span> 2011 The Good Thymes Virtual Grocery
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>footer</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>footer</span><span class="token punctuation">&gt;</span></span>
<span class="token entity named-entity" title="&amp;copy;">&amp;copy;</span> 2011 The Good Thymes Virtual Grocery
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>footer</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token entity named-entity" title="&amp;copy;">&amp;copy;</span> 2011 The Good Thymes Virtual Grocery
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

</code></pre></div><h2 id="_7、错误处理机制"><a href="#_7、错误处理机制" class="header-anchor">#</a> 7、错误处理机制</h2> <h3 id="_1-、springboot默认的错误处理机制"><a href="#_1-、springboot默认的错误处理机制" class="header-anchor">#</a> <strong>1</strong>）、SpringBoot默认的错误处理机制</h3> <p>默认效果：</p> <p>a、浏览器，返回一个默认的错误页面</p> <p><img src="http://ww1.sinaimg.cn/large/9b9f09a9ly1ga26j8yp0mj20kw084q39.jpg" alt="local-error.png"></p> <p>b、如果是其他客户端，默认响应一个json数据</p> <p>原理：</p> <p>可以参照ErrorMvcAutoConﬁguration；错误处理的自动配置； 给容器中添加了以下组件</p> <ol><li><p>DefaultErrorAttributes：帮我们在页面共享信息；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> <span class="token function">getErrorAttributes</span><span class="token punctuation">(</span><span class="token class-name">RequestAttributes</span> requestAttributes<span class="token punctuation">,</span>
                                              <span class="token keyword">boolean</span> includeStackTrace<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> errorAttributes <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LinkedHashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    errorAttributes<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;timestamp&quot;</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addStatus</span><span class="token punctuation">(</span>errorAttributes<span class="token punctuation">,</span> requestAttributes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addErrorDetails</span><span class="token punctuation">(</span>errorAttributes<span class="token punctuation">,</span> requestAttributes<span class="token punctuation">,</span> includeStackTrace<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addPath</span><span class="token punctuation">(</span>errorAttributes<span class="token punctuation">,</span> requestAttributes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> errorAttributes<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>BasicErrorController：处理默认/error请求</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Controller</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;${server.error.path:${error.path:/error}}&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BasicErrorController</span> <span class="token keyword">extends</span> <span class="token class-name">AbstractErrorController</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>produces <span class="token operator">=</span> <span class="token string">&quot;text/html&quot;</span><span class="token punctuation">)</span><span class="token comment">//产生html类型的数据；浏览器发送的请求来到这个方法处理</span>
    <span class="token keyword">public</span> <span class="token class-name">ModelAndView</span> <span class="token function">errorHtml</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span>
                                  <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">HttpStatus</span> status <span class="token operator">=</span> <span class="token function">getStatus</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> model <span class="token operator">=</span> <span class="token class-name">Collections</span><span class="token punctuation">.</span><span class="token function">unmodifiableMap</span><span class="token punctuation">(</span><span class="token function">getErrorAttributes</span><span class="token punctuation">(</span>
                request<span class="token punctuation">,</span> <span class="token function">isIncludeStackTrace</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> <span class="token class-name">MediaType</span><span class="token punctuation">.</span>TEXT_HTML<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        response<span class="token punctuation">.</span><span class="token function">setStatus</span><span class="token punctuation">(</span>status<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//去哪个页面作为错误页面；包含页面地址和页面内容</span>
        <span class="token class-name">ModelAndView</span> modelAndView <span class="token operator">=</span> <span class="token function">resolveErrorView</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> response<span class="token punctuation">,</span> status<span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token punctuation">(</span>modelAndView <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">ModelAndView</span><span class="token punctuation">(</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">,</span> model<span class="token punctuation">)</span> <span class="token operator">:</span> modelAndView<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token annotation punctuation">@RequestMapping</span>
    <span class="token annotation punctuation">@ResponseBody</span> <span class="token comment">//产生json数据，其他客户端来到这个方法处理；</span>
    <span class="token keyword">public</span> <span class="token class-name">ResponseEntity</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Map</span><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span><span class="token punctuation">&gt;</span></span> <span class="token function">error</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> body <span class="token operator">=</span> <span class="token function">getErrorAttributes</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span>
                <span class="token function">isIncludeStackTrace</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> <span class="token class-name">MediaType</span><span class="token punctuation">.</span>ALL<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">HttpStatus</span> status <span class="token operator">=</span> <span class="token function">getStatus</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ResponseEntity</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Map</span><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>body<span class="token punctuation">,</span> status<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre></div></li> <li><p>ErrorPageCustomizer：</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${error.path:/error}&quot;</span><span class="token punctuation">)</span>
<span class="token comment">//系统出现错误以后来到error请求进行处理；（web.xml注册的错误页面规则）</span>
<span class="token keyword">private</span> <span class="token class-name">String</span> path <span class="token operator">=</span> <span class="token string">&quot;/error&quot;</span><span class="token punctuation">;</span> 
</code></pre></div></li> <li><p>DefaultErrorViewResolver：</p> <div class="language-java extra-class"><pre class="language-java"><code>    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">ModelAndView</span> <span class="token function">resolveErrorView</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpStatus</span> status<span class="token punctuation">,</span>
                                         <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">ModelAndView</span> modelAndView <span class="token operator">=</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>status<span class="token punctuation">)</span><span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>modelAndView <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> SERIES_VIEWS<span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span>status<span class="token punctuation">.</span><span class="token function">series</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            modelAndView <span class="token operator">=</span> <span class="token function">resolve</span><span class="token punctuation">(</span>SERIES_VIEWS<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>status<span class="token punctuation">.</span><span class="token function">series</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> modelAndView<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">private</span> <span class="token class-name">ModelAndView</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token class-name">String</span> viewName<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">//默认SpringBoot可以去找到一个页面？ error/404</span>
        <span class="token class-name">String</span> errorViewName <span class="token operator">=</span> <span class="token string">&quot;error/&quot;</span> <span class="token operator">+</span> viewName<span class="token punctuation">;</span>
		<span class="token comment">//模板引擎可以解析这个页面地址就用模板引擎解析</span>
        <span class="token class-name">TemplateAvailabilityProvider</span> provider <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>templateAvailabilityProviders
                <span class="token punctuation">.</span><span class="token function">getProvider</span><span class="token punctuation">(</span>errorViewName<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>applicationContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>provider <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token comment">//模板引擎可用的情况下返回到errorViewName指定的视图地址</span>
            <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ModelAndView</span><span class="token punctuation">(</span>errorViewName<span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
		<span class="token comment">//模板引擎不可用，就在静态资源文件夹下找errorViewName对应的页面 error/404.html</span>
        <span class="token keyword">return</span> <span class="token function">resolveResource</span><span class="token punctuation">(</span>errorViewName<span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> 
</code></pre></div></li></ol> <p>步骤：</p> <p>一但系统出现4xx或者5xx之类的错误；ErrorPageCustomizer就会生效（定制错误的响应规则）；就会来到/error 请求；就会被<strong>BasicErrorController</strong>处理；</p> <ol><li><p>响应页面；去哪个页面是由<strong>DefaultErrorViewResolver</strong>解析得到的；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">protected</span> <span class="token class-name">ModelAndView</span> <span class="token function">resolveErrorView</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span>
                                        <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">HttpStatus</span> status<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//所有的ErrorViewResolver得到ModelAndView</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">ErrorViewResolver</span> resolver <span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>errorViewResolvers<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">ModelAndView</span> modelAndView <span class="token operator">=</span> resolver<span class="token punctuation">.</span><span class="token function">resolveErrorView</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> status<span class="token punctuation">,</span> model<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>modelAndView <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> modelAndView<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ol> <h3 id="_2-、如何定制错误响应"><a href="#_2-、如何定制错误响应" class="header-anchor">#</a> 2)、如何定制错误响应：</h3> <p>a. 如何定制错误的页面；</p> <ul><li><p>有模板引擎的情况下；<strong>error/<strong>状态码</strong>;</strong> 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面error		文件夹下】，发生此状态码的错误就会来到对应的页面；</p> <p>我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误，精确优先（优先寻找精确的状态  		码.html）；</p> <p>页面能获取的信息:timestamp：</p> <ul><li>时间戳</li> <li>status：状态码</li> <li>error：错误提示exception：异常对象</li> <li>message：异常消息</li> <li>errors：JSR303数据校验的错误都在这里</li></ul></li> <li><p>没有模板引擎（模板引擎找不到这个错误页面），静态资源文件夹下找；</p></li> <li><p>以上都没有错误页面，就是默认来到SpringBoot默认的错误提示页面；</p></li></ul> <p>b. 如何定制错误的<strong>json</strong>数据；</p> <ul><li><p>自定义异常处理&amp;返回定制json数据；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ControllerAdvice</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyExceptionHandler</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span><span class="token class-name">UserNotExistException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> <span class="token function">handleException</span><span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;code&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;user.notexist&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">,</span>e<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//没有自适应效果...</span>
</code></pre></div></li> <li><p>转发到/error进行自适应响应效果处理</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span><span class="token class-name">UserNotExistException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">handleException</span><span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">,</span> <span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//传入我们自己的错误状态码 4xx 5xx，否则就不会进入定制错误页面的解析流程</span>
    <span class="token comment">/**
    * Integer statusCode = (Integer) request
    .getAttribute(&quot;javax.servlet.error.status_code&quot;);
    */</span>
    request<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&quot;javax.servlet.error.status_code&quot;</span><span class="token punctuation">,</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;code&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;user.notexist&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">,</span>e<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//转发到/error</span>
    <span class="token keyword">return</span> <span class="token string">&quot;forward:/error&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul> <h3 id="_3-、将我们的定制数据携带出去"><a href="#_3-、将我们的定制数据携带出去" class="header-anchor">#</a> 3）、将我们的定制数据携带出去；</h3> <p>出现错误以后，会来到/error请求，会被BasicErrorController处理，响应出去可以获取的数据是由</p> <p>getErrorAttributes得到的（是AbstractErrorController（ErrorController）规定的方法）；</p> <ol><li><p>完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】，放在容器中；</p></li> <li><p>页面上能用的数据，或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到； 容器中DefaultErrorAttributes.getErrorAttributes()；默认进行数据处理的；</p> <p>自定义ErrorAttributes</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//给容器中加入我们自己定义的ErrorAttributes</span>
<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyErrorAttributes</span> <span class="token keyword">extends</span> <span class="token class-name">DefaultErrorAttributes</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> <span class="token function">getErrorAttributes</span><span class="token punctuation">(</span><span class="token class-name">RequestAttributes</span> requestAttributes<span class="token punctuation">,</span>
                                                  <span class="token keyword">boolean</span> includeStackTrace<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">getErrorAttributes</span><span class="token punctuation">(</span>requestAttributes<span class="token punctuation">,</span>
                includeStackTrace<span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;company&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;atguigu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>最终的效果：响应是自适应的，可以通过定制ErrorAttributes改变需要返回的内容，</p></li></ol> <h2 id="_8、配置嵌入式servlet容器"><a href="#_8、配置嵌入式servlet容器" class="header-anchor">#</a> <strong>8</strong>、配置嵌入式<strong>Servlet</strong>容器</h2> <p>SpringBoot默认使用Tomcat作为嵌入式的Servlet容器；</p> <h3 id="_1-、如何定制和修改servlet容器的相关配置"><a href="#_1-、如何定制和修改servlet容器的相关配置" class="header-anchor">#</a> <strong>1</strong>）、如何定制和修改<strong>Servlet</strong>容器的相关配置；</h3> <ol><li><p>修改和server有关的配置（ServerProperties【也是EmbeddedServletContainerCustomizer】）；</p> <div class="language-properties extra-class"><pre class="language-properties"><code><span class="token attr-name">server.port</span><span class="token punctuation">=</span><span class="token attr-value">8081</span>
<span class="token attr-name">server.context‐path</span><span class="token punctuation">=</span><span class="token attr-value">/crud</span>
<span class="token attr-name">server.tomcat.uri‐encoding</span><span class="token punctuation">=</span><span class="token attr-value">UTF‐8</span>
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx
</code></pre></div></li> <li><p>编写一个<strong>EmbeddedServletContainerCustomizer</strong>：嵌入式的Servlet容器的定制器；来修改Servlet容器的配置</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span> <span class="token comment">//一定要将这个定制器加入到容器中</span>
<span class="token keyword">public</span> <span class="token class-name">EmbeddedServletContainerCustomizer</span> <span class="token function">embeddedServletContainerCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">EmbeddedServletContainerCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//定制嵌入式的Servlet容器相关的规则</span>
        <span class="token annotation punctuation">@Override</span>
        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">ConfigurableEmbeddedServletContainer</span> container<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            container<span class="token punctuation">.</span><span class="token function">setPort</span><span class="token punctuation">(</span><span class="token number">8083</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ol> <h3 id="_2-、注册servlet三大组件【servlet、filter、listener】"><a href="#_2-、注册servlet三大组件【servlet、filter、listener】" class="header-anchor">#</a> <strong>2</strong>）、注册Servlet三大组件【Servlet、Filter、Listener】</h3> <p>由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用，没有web.xml文 件。</p> <p>注册三大组件用以下方式</p> <p><strong>ServletRegistrationBean</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//注册三大组件</span>
<span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">ServletRegistrationBean</span> <span class="token function">myServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
	<span class="token class-name">ServletRegistrationBean</span> registrationBean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ServletRegistrationBean</span><span class="token punctuation">(</span><span class="token keyword">new</span>
<span class="token class-name">MyServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token string">&quot;/myServlet&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> registrationBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>FilterRegistrationBean</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">FilterRegistrationBean</span> <span class="token function">myFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">FilterRegistrationBean</span> registrationBean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FilterRegistrationBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    registrationBean<span class="token punctuation">.</span><span class="token function">setFilter</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MyFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    registrationBean<span class="token punctuation">.</span><span class="token function">setUrlPatterns</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">asList</span><span class="token punctuation">(</span><span class="token string">&quot;/hello&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;/myServlet&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> registrationBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>ServletListenerRegistrationBean</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">ServletListenerRegistrationBean</span> <span class="token function">myListener</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">ServletListenerRegistrationBean</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">MyListener</span><span class="token punctuation">&gt;</span></span> registrationBean <span class="token operator">=</span> <span class="token keyword">new</span>
    <span class="token class-name">ServletListenerRegistrationBean</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MyListener</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> registrationBean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>SpringBoot帮我们自动配置SpringMVC的时候，自动的注册SpringMVC的前端控制器；DIspatcherServlet；</p> <p><strong>DispatcherServletAutoConﬁguration</strong>中：</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span>name <span class="token operator">=</span> DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME<span class="token punctuation">)</span>
<span class="token annotation punctuation">@ConditionalOnBean</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">DispatcherServlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> name <span class="token operator">=</span>
                   DEFAULT_DISPATCHER_SERVLET_BEAN_NAME<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">ServletRegistrationBean</span> <span class="token function">dispatcherServletRegistration</span><span class="token punctuation">(</span>
    <span class="token class-name">DispatcherServlet</span> dispatcherServlet<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">ServletRegistrationBean</span> registration <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ServletRegistrationBean</span><span class="token punctuation">(</span>
        dispatcherServlet<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>serverProperties<span class="token punctuation">.</span><span class="token function">getServletMapping</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//默认拦截： / 所有请求；包静态资源，但是不拦截jsp请求； /*会拦截jsp</span>
    <span class="token comment">//可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径</span>
    registration<span class="token punctuation">.</span><span class="token function">setName</span><span class="token punctuation">(</span>DEFAULT_DISPATCHER_SERVLET_BEAN_NAME<span class="token punctuation">)</span><span class="token punctuation">;</span>
    registration<span class="token punctuation">.</span><span class="token function">setLoadOnStartup</span><span class="token punctuation">(</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>webMvcProperties<span class="token punctuation">.</span><span class="token function">getServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getLoadOnStartup</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>multipartConfig <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        registration<span class="token punctuation">.</span><span class="token function">setMultipartConfig</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>multipartConfig<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> registration<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_3-、替换为其他嵌入式servlet容器"><a href="#_3-、替换为其他嵌入式servlet容器" class="header-anchor">#</a> <strong>3</strong>）、替换为其他嵌入式<strong>Servlet</strong>容器</h3> <p>默认支持：</p> <p>Tomcat（默认使用）</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器；
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>Jetty</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span> <span class="token attr-name">引入web模块</span> <span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusions</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐tomcat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusions</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐引入其他的Servlet容器‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐jetty<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>

</code></pre></div><p>Undertow</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span> <span class="token attr-name">引入web模块</span> <span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐web<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusions</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>exclusion</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐tomcat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusion</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>exclusions</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐引入其他的Servlet容器‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐undertow<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_4-、嵌入式servlet容器自动配置原理"><a href="#_4-、嵌入式servlet容器自动配置原理" class="header-anchor">#</a> <strong>4</strong>）、嵌入式Servlet容器自动配置原理；</h3> <p>EmbeddedServletContainerAutoConﬁguration：嵌入式的Servlet容器自动配置？</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@AutoConfigureOrder</span><span class="token punctuation">(</span><span class="token class-name">Ordered</span><span class="token punctuation">.</span>HIGHEST_PRECEDENCE<span class="token punctuation">)</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ConditionalOnWebApplication</span>
<span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token class-name">BeanPostProcessorsRegistrar</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token comment">//导入BeanPostProcessorsRegistrar：Spring注解版；给容器中导入一些组件</span>
<span class="token comment">//导入了EmbeddedServletContainerCustomizerBeanPostProcessor：</span>
<span class="token comment">//后置处理器：bean初始化前后（创建完对象，还没赋值赋值）执行初始化工作</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">EmbeddedServletContainerAutoConfiguration</span> <span class="token punctuation">{</span>
   <span class="token annotation punctuation">@Configuration</span>
   <span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">Servlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">Tomcat</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token comment">//判断当前是否引入了Tomcat依赖；</span>
   <span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">EmbeddedServletContainerFactory</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> search <span class="token operator">=</span>
           <span class="token class-name">SearchStrategy</span><span class="token punctuation">.</span>CURRENT<span class="token punctuation">)</span><span class="token comment">//判断当前容器没有用户自己定义EmbeddedServletContainerFactory：嵌入式的</span>
   <span class="token class-name">Servlet</span>容器工厂；作用：创建嵌入式的<span class="token class-name">Servlet</span>容器
   <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">EmbeddedTomcat</span> <span class="token punctuation">{</span>
       <span class="token annotation punctuation">@Bean</span>
       <span class="token keyword">public</span> <span class="token class-name">TomcatEmbeddedServletContainerFactory</span> <span class="token function">tomcatEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
       <span class="token punctuation">{</span>
           <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">TomcatEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token punctuation">}</span>
   <span class="token punctuation">}</span>
   <span class="token comment">/**
    * Nested configuration if Jetty is being used.
    */</span>
   <span class="token annotation punctuation">@Configuration</span>
   <span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">Servlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">Server</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">Loader</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>
           <span class="token class-name">WebAppContext</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
   <span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">EmbeddedServletContainerFactory</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> search <span class="token operator">=</span>
           <span class="token class-name">SearchStrategy</span><span class="token punctuation">.</span>CURRENT<span class="token punctuation">)</span>
   <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">EmbeddedJetty</span> <span class="token punctuation">{</span>
       <span class="token annotation punctuation">@Bean</span>
       <span class="token keyword">public</span> <span class="token class-name">JettyEmbeddedServletContainerFactory</span> <span class="token function">jettyEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
           <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">JettyEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token punctuation">}</span>
   <span class="token punctuation">}</span>
   <span class="token comment">/**
    * Nested configuration if Undertow is being used.
    */</span>
   <span class="token annotation punctuation">@Configuration</span>
   <span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token class-name">Servlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">Undertow</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">SslClientAuthMode</span><span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
   <span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token class-name">EmbeddedServletContainerFactory</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> search <span class="token operator">=</span>
           <span class="token class-name">SearchStrategy</span><span class="token punctuation">.</span>CURRENT<span class="token punctuation">)</span>
   <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">EmbeddedUndertow</span> <span class="token punctuation">{</span>
       <span class="token annotation punctuation">@Bean</span>
       <span class="token keyword">public</span> <span class="token class-name">UndertowEmbeddedServletContainerFactory</span>
       <span class="token function">undertowEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
           <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UndertowEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token punctuation">}</span>
   <span class="token punctuation">}</span>
</code></pre></div><ol><li><p>EmbeddedServletContainerFactory（嵌入式Servlet容器工厂）</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">EmbeddedServletContainerFactory</span> <span class="token punctuation">{</span>
    <span class="token comment">//获取嵌入式的Servlet容器</span>
    <span class="token class-name">EmbeddedServletContainer</span> <span class="token function">getEmbeddedServletContainer</span><span class="token punctuation">(</span>
    <span class="token class-name">ServletContextInitializer</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> initializers<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>EmbeddedServletContainer：（嵌入式的Servlet容器）</p></li> <li><p>以<strong>TomcatEmbeddedServletContainerFactory</strong>为例</p> <div class="language-java extra-class"><pre class="language-java"><code> <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">EmbeddedServletContainer</span> <span class="token function">getEmbeddedServletContainer</span><span class="token punctuation">(</span>
            <span class="token class-name">ServletContextInitializer</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> initializers<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//创建一个Tomcat</span>
        <span class="token class-name">Tomcat</span> tomcat <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Tomcat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//配置Tomcat的基本环节</span>
        <span class="token class-name">File</span> baseDir <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>baseDirectory <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">?</span> <span class="token keyword">this</span><span class="token punctuation">.</span>baseDirectory
                <span class="token operator">:</span> <span class="token function">createTempDir</span><span class="token punctuation">(</span><span class="token string">&quot;tomcat&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        tomcat<span class="token punctuation">.</span><span class="token function">setBaseDir</span><span class="token punctuation">(</span>baseDir<span class="token punctuation">.</span><span class="token function">getAbsolutePath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Connector</span> connector <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Connector</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>protocol<span class="token punctuation">)</span><span class="token punctuation">;</span>
        tomcat<span class="token punctuation">.</span><span class="token function">getService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addConnector</span><span class="token punctuation">(</span>connector<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">customizeConnector</span><span class="token punctuation">(</span>connector<span class="token punctuation">)</span><span class="token punctuation">;</span>
        tomcat<span class="token punctuation">.</span><span class="token function">setConnector</span><span class="token punctuation">(</span>connector<span class="token punctuation">)</span><span class="token punctuation">;</span>
        tomcat<span class="token punctuation">.</span><span class="token function">getHost</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setAutoDeploy</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">configureEngine</span><span class="token punctuation">(</span>tomcat<span class="token punctuation">.</span><span class="token function">getEngine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Connector</span> additionalConnector <span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>additionalTomcatConnectors<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            tomcat<span class="token punctuation">.</span><span class="token function">getService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addConnector</span><span class="token punctuation">(</span>additionalConnector<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token function">prepareContext</span><span class="token punctuation">(</span>tomcat<span class="token punctuation">.</span><span class="token function">getHost</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> initializers<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//将配置好的Tomcat传入进去，返回一个EmbeddedServletContainer；并且启动Tomcat服务器</span>
        <span class="token keyword">return</span> <span class="token function">getTomcatEmbeddedServletContainer</span><span class="token punctuation">(</span>tomcat<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>我们对嵌入式容器的配置修改是怎么生效？</p> <div class="language- extra-class"><pre class="language-text"><code>ServerProperties、EmbeddedServletContainerCustomizer
</code></pre></div><p><strong>EmbeddedServletContainerCustomizer</strong>：定制器帮我们修改了Servlet容器的配置？ 怎么修改的原理？</p> <p>容器中导入了EmbeddedServletContainerCustomizerBeanPostProcessor</p> <div class="language-java extra-class"><pre class="language-java"><code> <span class="token comment">//初始化之前</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">Object</span> <span class="token function">postProcessBeforeInitialization</span><span class="token punctuation">(</span><span class="token class-name">Object</span> bean<span class="token punctuation">,</span> <span class="token class-name">String</span> beanName<span class="token punctuation">)</span>
            <span class="token keyword">throws</span> <span class="token class-name">BeansException</span> <span class="token punctuation">{</span>
<span class="token comment">//如果当前初始化的是一个ConfigurableEmbeddedServletContainer类型的组件</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>bean <span class="token keyword">instanceof</span> <span class="token class-name">ConfigurableEmbeddedServletContainer</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//</span>
            <span class="token function">postProcessBeforeInitialization</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">ConfigurableEmbeddedServletContainer</span><span class="token punctuation">)</span> bean<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> bean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">postProcessBeforeInitialization</span><span class="token punctuation">(</span>
            <span class="token class-name">ConfigurableEmbeddedServletContainer</span> bean<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//获取所有的定制器，调用每一个定制器的customize方法来给Servlet容器进行属性赋值；</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">EmbeddedServletContainerCustomizer</span> customizer <span class="token operator">:</span> <span class="token function">getCustomizers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            customizer<span class="token punctuation">.</span><span class="token function">customize</span><span class="token punctuation">(</span>bean<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">private</span> <span class="token class-name">Collection</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">EmbeddedServletContainerCustomizer</span><span class="token punctuation">&gt;</span></span> <span class="token function">getCustomizers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>customizers <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Look up does not include the parent context</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>customizers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">EmbeddedServletContainerCustomizer</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>
                    <span class="token keyword">this</span><span class="token punctuation">.</span>beanFactory
<span class="token comment">//从容器中获取所有这葛类型的组件：EmbeddedServletContainerCustomizer</span>
<span class="token comment">//定制Servlet容器，给容器中可以添加一个EmbeddedServletContainerCustomizer类型的组件</span>
                            <span class="token punctuation">.</span><span class="token function">getBeansOfType</span><span class="token punctuation">(</span><span class="token class-name">EmbeddedServletContainerCustomizer</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>
                                    <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
                            <span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">Collections</span><span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>customizers<span class="token punctuation">,</span> <span class="token class-name">AnnotationAwareOrderComparator</span><span class="token punctuation">.</span>INSTANCE<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>customizers <span class="token operator">=</span> <span class="token class-name">Collections</span><span class="token punctuation">.</span><span class="token function">unmodifiableList</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>customizers<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>customizers<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token class-name">ServerProperties</span>也是定制器
</code></pre></div><p>步骤：</p> <p>a、SpringBoot根据导入的依赖情况，给容器中添加相应的</p> <p>​		EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】</p> <p>b、容器中某个组件要创建对象就会惊动后置处理器；	EmbeddedServletContainerCustomizerBeanPostProcessor；</p> <p>只要是嵌入式的Servlet容器工厂，后置处理器就工作；</p> <p>c、后置处理器，从容器中获取所有的<strong>EmbeddedServletContainerCustomizer</strong>，调用定制器的定制方法</p></li></ol> <h3 id="_5-、嵌入式servlet容器启动原理"><a href="#_5-、嵌入式servlet容器启动原理" class="header-anchor">#</a> 5）、嵌入式Servlet容器启动原理；</h3> <p>什么时候创建嵌入式的Servlet容器工厂？</p> <p>什么时候获取嵌入式的Servlet容器并启动Tomcat； 获取嵌入式的Servlet容器工厂：</p> <ol><li><p>SpringBoot应用启动运行run方法</p></li> <li><p>refreshContext(context);SpringBoot刷新IOC容器【创建IOC容器对象，并初始化容器，创建容器中的每一个 组 件 】 ； 如 果 是 web 应 用 创 建 <strong>AnnotationConﬁgEmbeddedWebApplicationContext</strong>， 否 则 ： <strong>AnnotationConﬁgApplicationContext</strong></p></li> <li><p>refresh(context);刷新刚才创建好的<strong>ioc</strong>容器；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">refresh</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">BeansException</span><span class="token punctuation">,</span> <span class="token class-name">IllegalStateException</span> <span class="token punctuation">{</span>
<span class="token keyword">synchronized</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>startupShutdownMonitor<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Prepare this context for refreshing.</span>
<span class="token function">prepareRefresh</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Tell the subclass to refresh the internal bean factory.</span>
<span class="token class-name">ConfigurableListableBeanFactory</span> beanFactory <span class="token operator">=</span> <span class="token function">obtainFreshBeanFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Prepare the bean factory for use in this context.</span>
<span class="token function">prepareBeanFactory</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token comment">// Allows post‐processing of the bean factory in context subclasses.</span>

</code></pre></div></li> <li><p>onRefresh(); web的ioc容器重写了onRefresh方法</p></li> <li><p>webioc容器会创建嵌入式的Servlet容器；<strong>createEmbeddedServletContainer</strong>();</p></li> <li><p>获取嵌入式的<strong>Servlet</strong>容器工厂：</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token class-name">EmbeddedServletContainerFactory</span> containerFactory <span class="token operator">=</span> <span class="token function">getEmbeddedServletContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>从ioc容器中获取EmbeddedServletContainerFactory 组件；<strong>TomcatEmbeddedServletContainerFactory</strong>创建对象，后置处理器一看是这个对象，就获取所有的定制器来先定制Servlet容器的相关配置；</p></li> <li><p>使用容器工厂获取嵌入式的<strong>Servlet</strong>容器：</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">this</span><span class="token punctuation">.</span>embeddedServletContainer <span class="token operator">=</span> containerFactory
<span class="token punctuation">.</span><span class="token function">getEmbeddedServletContainer</span><span class="token punctuation">(</span><span class="token function">getSelfInitializer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li> <li><p>嵌入式的Servlet容器创建对象并启动Servlet容器；</p> <p>先启动嵌入式的<strong>Servlet</strong>容器，再将<strong>ioc</strong>容器中剩下没有创建出的对象获取出来；</p> <p><strong>IOC</strong>容器启动创建嵌入式的<strong>Servlet</strong>容器</p></li></ol> <h2 id="_9、使用外置的servlet容器"><a href="#_9、使用外置的servlet容器" class="header-anchor">#</a> 9、使用外置的Servlet容器</h2> <h3 id="_9-1-嵌入式servlet容器"><a href="#_9-1-嵌入式servlet容器" class="header-anchor">#</a> 9.1. 嵌入式Servlet容器：</h3> <p><strong>应用打成可执行的jar</strong></p> <p>优点：简单、便携；</p> <p>缺点：默认不支持JSP、优化定制比较复杂（使用定制器【ServerProperties、自定义</p> <p>EmbeddedServletContainerCustomizer】，自己编写嵌入式Servlet容器的创建工厂</p> <p>【EmbeddedServletContainerFactory】）；</p> <h3 id="_9-2-外置的servlet容器"><a href="#_9-2-外置的servlet容器" class="header-anchor">#</a> 9.2. 外置的Servlet容器</h3> <p>外面安装Tomcat---应用war包的方式打包；</p> <p>步骤</p> <ol><li><p>必须创建一个war项目；（利用idea创建好目录结构）</p></li> <li><p>将嵌入式的Tomcat指定为provided；</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐tomcat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>provided<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
 
</code></pre></div></li> <li><p>必须编写一个<strong>SpringBootServletInitializer</strong>的子类，并调用conﬁgure方法</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServletInitializer</span> <span class="token keyword">extends</span> <span class="token class-name">SpringBootServletInitializer</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token class-name">SpringApplicationBuilder</span> <span class="token function">configure</span><span class="token punctuation">(</span><span class="token class-name">SpringApplicationBuilder</span> application<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//传入SpringBoot应用的主程序</span>
        <span class="token keyword">return</span> application<span class="token punctuation">.</span><span class="token function">sources</span><span class="token punctuation">(</span><span class="token class-name">SpringBoot04WebJspApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>启动服务器就可以使用；</p></li></ol> <h3 id="_9-3-原理"><a href="#_9-3-原理" class="header-anchor">#</a> 9.3. 原理</h3> <ul><li><p>jar包：执行SpringBoot主类的main方法——&gt;启动ioc容器——&gt;创建嵌入式的Servlet容器；</p></li> <li><p>war包：启动服务器——&gt;服务器启动<strong>SpringBoot</strong>应用【SpringBootServletInitializer】——&gt;启动ioc容器；</p></li></ul> <p><strong>servlet3.0（Spring注解版）：</strong></p> <p>Shared libraries / runtimes pluggability： 规则：</p> <ol><li><p>服务器启动（web应用启动）会创建当前web应用里面每一个jar包里面ServletContainerInitializer实例：</p></li> <li><p>ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下，有一个名为</p> <p>javax.servlet.ServletContainerInitializer的文件，内容就是ServletContainerInitializer的实现类的全类名</p></li> <li><p>还可以使用@HandlesTypes，在应用启动的时候加载我们感兴趣的类；</p></li></ol> <p><strong>流程：</strong></p> <ol><li><p>启动Tomcat</p></li> <li><p>org\springframework\spring-web\4.3.14.RELEASE\spring-web-4.3.14.RELEASE.jar!\META- INF\services\javax.servlet.ServletContainerInitializer：</p> <p>Spring的web模块里面有这个文件：<strong>org.springframework.web.SpringServletContainerInitializer</strong></p></li> <li><p>SpringServletContainerInitializer将@HandlesTypes(WebApplicationInitializer.class)标注的所有这个类型的类都传入到onStartup方法的Set&gt;；为这些WebApplicationInitializer类型的类创建实例；</p></li> <li><p>每一个WebApplicationInitializer都调用自己的onStartup；</p></li> <li><p>相当于我们的SpringBootServletInitializer的类会被创建对象，并执行onStartup方法</p></li> <li><p>SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext；创建容器</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">protected</span> <span class="token class-name">WebApplicationContext</span> <span class="token function">createRootApplicationContext</span><span class="token punctuation">(</span>
            <span class="token class-name">ServletContext</span> servletContext<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//1、创建SpringApplicationBuilder</span>
        <span class="token class-name">SpringApplicationBuilder</span> builder <span class="token operator">=</span> <span class="token function">createSpringApplicationBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">StandardServletEnvironment</span> environment <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">StandardServletEnvironment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        environment<span class="token punctuation">.</span><span class="token function">initPropertySources</span><span class="token punctuation">(</span>servletContext<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        builder<span class="token punctuation">.</span><span class="token function">environment</span><span class="token punctuation">(</span>environment<span class="token punctuation">)</span><span class="token punctuation">;</span>
        builder<span class="token punctuation">.</span><span class="token function">main</span><span class="token punctuation">(</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">ApplicationContext</span> parent <span class="token operator">=</span> <span class="token function">getExistingRootWebApplicationContext</span><span class="token punctuation">(</span>servletContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>parent <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>logger<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">&quot;Root context already created (using as parent).&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            servletContext<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span>
                    <span class="token class-name">WebApplicationContext</span><span class="token punctuation">.</span>ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            builder<span class="token punctuation">.</span><span class="token function">initializers</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ParentContextApplicationContextInitializer</span><span class="token punctuation">(</span>parent<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        builder<span class="token punctuation">.</span><span class="token function">initializers</span><span class="token punctuation">(</span>
                <span class="token keyword">new</span> <span class="token class-name">ServletContextApplicationContextInitializer</span><span class="token punctuation">(</span>servletContext<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        builder<span class="token punctuation">.</span><span class="token function">contextClass</span><span class="token punctuation">(</span><span class="token class-name">AnnotationConfigEmbeddedWebApplicationContext</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//调用configure方法，子类重写了这个方法，将SpringBoot的主程序类传入了进来</span>
        builder <span class="token operator">=</span> <span class="token function">configure</span><span class="token punctuation">(</span>builder<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//使用builder创建一个Spring应用</span>
        <span class="token class-name">SpringApplication</span> application <span class="token operator">=</span> builder<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>application<span class="token punctuation">.</span><span class="token function">getSources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token class-name">AnnotationUtils</span>
                <span class="token punctuation">.</span><span class="token function">findAnnotation</span><span class="token punctuation">(</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">Configuration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            application<span class="token punctuation">.</span><span class="token function">getSources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token class-name">Assert</span><span class="token punctuation">.</span><span class="token function">state</span><span class="token punctuation">(</span><span class="token operator">!</span>application<span class="token punctuation">.</span><span class="token function">getSources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token string">&quot;No SpringApplication sources have been defined. Either override the &quot;</span>
                        <span class="token operator">+</span> <span class="token string">&quot;configure method or add an @Configuration annotation&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Ensure error pages are registered</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>registerErrorPageFilter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            application<span class="token punctuation">.</span><span class="token function">getSources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token class-name">ErrorPageFilterConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
<span class="token comment">//启动Spring应用</span>
        <span class="token keyword">return</span> <span class="token function">run</span><span class="token punctuation">(</span>application<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre></div></li> <li><p>Spring的应用就启动并且创建IOC容器</p> <div class="language-java extra-class"><pre class="language-java"><code> <span class="token keyword">public</span> <span class="token class-name">ConfigurableApplicationContext</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">StopWatch</span> stopWatch <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">StopWatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        stopWatch<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">ConfigurableApplicationContext</span> context <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token class-name">FailureAnalyzers</span> analyzers <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token function">configureHeadlessProperty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">SpringApplicationRunListeners</span> listeners <span class="token operator">=</span> <span class="token function">getRunListeners</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
        listeners<span class="token punctuation">.</span><span class="token function">starting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">try</span> <span class="token punctuation">{</span>
            <span class="token class-name">ApplicationArguments</span> applicationArguments <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DefaultApplicationArguments</span><span class="token punctuation">(</span>
                    args<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">ConfigurableEnvironment</span> environment <span class="token operator">=</span> <span class="token function">prepareEnvironment</span><span class="token punctuation">(</span>listeners<span class="token punctuation">,</span>
                    applicationArguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">Banner</span> printedBanner <span class="token operator">=</span> <span class="token function">printBanner</span><span class="token punctuation">(</span>environment<span class="token punctuation">)</span><span class="token punctuation">;</span>
            context <span class="token operator">=</span> <span class="token function">createApplicationContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            analyzers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FailureAnalyzers</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">prepareContext</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> environment<span class="token punctuation">,</span> listeners<span class="token punctuation">,</span> applicationArguments<span class="token punctuation">,</span>
                    printedBanner<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//刷新IOC容器</span>
            <span class="token function">refreshContext</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">afterRefresh</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> applicationArguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
            listeners<span class="token punctuation">.</span><span class="token function">finished</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            stopWatch<span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>logStartupInfo<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">new</span> <span class="token class-name">StartupInfoLogger</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mainApplicationClass<span class="token punctuation">)</span>
                        <span class="token punctuation">.</span><span class="token function">logStarted</span><span class="token punctuation">(</span><span class="token function">getApplicationLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stopWatch<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">return</span> context<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Throwable</span> ex<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">handleRunFailure</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> listeners<span class="token punctuation">,</span> analyzers<span class="token punctuation">,</span> ex<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">IllegalStateException</span><span class="token punctuation">(</span>ex<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

</code></pre></div></li></ol> <p>启动<strong>Servlet</strong>容器，再启动<strong>SpringBoot</strong>应用</p> <hr> <h1 id="五、springboot与数据访问"><a href="#五、springboot与数据访问" class="header-anchor">#</a> 五、SpringBoot与数据访问</h1> <h2 id="_1、jdbc"><a href="#_1、jdbc" class="header-anchor">#</a> <strong>1</strong>、JDBC</h2> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐jdbc<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>mysql<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>mysql‐connector‐java<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">datasource</span><span class="token punctuation">:</span>
  <span class="token key atrule">username</span><span class="token punctuation">:</span> root
  <span class="token key atrule">password</span><span class="token punctuation">:</span> <span class="token number">123456</span>
  <span class="token key atrule">url</span><span class="token punctuation">:</span> jdbc<span class="token punctuation">:</span>mysql<span class="token punctuation">:</span>//192.168.15.22<span class="token punctuation">:</span>3306/jdbc
  <span class="token key atrule">driver‐class‐name</span><span class="token punctuation">:</span> com.mysql.jdbc.Driver
</code></pre></div><p>默认是用org.apache.tomcat.jdbc.pool.DataSource作为数据源；</p> <p>数据源的相关配置都在DataSourceProperties里面；</p> <p>自动配置原理：</p> <p><strong>org.springframework.boot.autoconﬁgure.jdbc</strong>：</p> <ol><li><p>参考DataSourceConﬁguration，根据配置创建数据源，默认使用Tomcat连接池；可以使用</p> <p>spring.datasource.type指定自定义的数据源类型；</p></li> <li><p>SpringBoot默认可以支持；</p> <div class="language- extra-class"><pre class="language-text"><code>org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource、
</code></pre></div></li> <li><p>自定义数据源类型</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">/**
* Generic DataSource configuration.
*/</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span><span class="token class-name">DataSource</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ConditionalOnProperty</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;spring.datasource.type&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Generic</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">DataSource</span> <span class="token function">dataSource</span><span class="token punctuation">(</span><span class="token class-name">DataSourceProperties</span> properties<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">//使用DataSourceBuilder创建数据源，利用反射创建响应type的数据源，并且绑定相关属性</span>
	<span class="token keyword">return</span> properties<span class="token punctuation">.</span><span class="token function">initializeDataSourceBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div></li> <li><p><strong>DataSourceInitializer</strong>：<strong>ApplicationListener</strong>；</p> <p>作用：</p></li></ol> <ul><li><p>runSchemaScripts();运行建表语句；</p></li> <li><p>runDataScripts();运行插入数据的sql语句；</p></li></ul> <p>默认只需要将文件命名为：</p> <div class="language-xml extra-class"><pre class="language-xml"><code>schema‐*.sql、data‐*.sql
默认规则：schema.sql，schema‐all.sql；
可以使用
schema:
‐ classpath:department.sql
指定位置
</code></pre></div><ol start="5"><li>操作数据库：自动配置了JdbcTemplate操作数据库</li></ol> <h2 id="_2、整合druid数据源"><a href="#_2、整合druid数据源" class="header-anchor">#</a> <strong>2</strong>、整合Druid数据源</h2> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.alibaba<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>druid-spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.1.10<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">DruidConfig</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;spring.datasource&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">DataSource</span> <span class="token function">druid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">DruidDataSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//配置Druid的监控</span>
<span class="token comment">//1、配置一个管理后台的Servlet</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">ServletRegistrationBean</span> <span class="token function">statViewServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">ServletRegistrationBean</span> bean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ServletRegistrationBean</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">StatViewServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token string">&quot;/druid/*&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> initParams <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        initParams<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;loginUsername&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;admin&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        initParams<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;loginPassword&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;123456&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        initParams<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;allow&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//默认就是允许所有访问</span>
        initParams<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;deny&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;192.168.15.21&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setInitParameters</span><span class="token punctuation">(</span>initParams<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> bean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//2、配置一个web监控的filter</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">FilterRegistrationBean</span> <span class="token function">webStatFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">FilterRegistrationBean</span> bean <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FilterRegistrationBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setFilter</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">WebStatFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> initParams <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        initParams<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">&quot;exclusions&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;*.js,*.css,/druid/*&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setInitParameters</span><span class="token punctuation">(</span>initParams<span class="token punctuation">)</span><span class="token punctuation">;</span>
        bean<span class="token punctuation">.</span><span class="token function">setUrlPatterns</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">asList</span><span class="token punctuation">(</span><span class="token string">&quot;/*&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> bean<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="_3、整合mybatis"><a href="#_3、整合mybatis" class="header-anchor">#</a> <strong>3</strong>、整合<strong>MyBatis</strong></h2> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.mybatis.spring.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>mybatis‐spring‐boot‐starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.3.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>步骤：</p> <ol><li><p>配置数据源相关属性</p></li> <li><p>给数据库建表</p></li> <li><p>创建JavaBean</p></li> <li><p>注解版</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//指定这是一个操作数据库的mapper</span>
<span class="token annotation punctuation">@Mapper</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">DepartmentMapper</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Select</span><span class="token punctuation">(</span><span class="token string">&quot;select * from department where id=#{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Department</span> <span class="token function">getDeptById</span><span class="token punctuation">(</span><span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Delete</span><span class="token punctuation">(</span><span class="token string">&quot;delete from department where id=#{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">deleteDeptById</span><span class="token punctuation">(</span><span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Options</span><span class="token punctuation">(</span>useGeneratedKeys <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span>keyProperty <span class="token operator">=</span> <span class="token string">&quot;id&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@Insert</span><span class="token punctuation">(</span><span class="token string">&quot;insert into department(departmentName) values(#{departmentName})&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">insertDept</span><span class="token punctuation">(</span><span class="token class-name">Department</span> department<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Update</span><span class="token punctuation">(</span><span class="token string">&quot;update department set departmentName=#{departmentName} where id=#{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">updateDept</span><span class="token punctuation">(</span><span class="token class-name">Department</span> department<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>问题：</p> <p>自定义MyBatis的配置规则；给容器中添加一个ConﬁgurationCustomizer；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@org</span><span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span><span class="token class-name">Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBatisConfig</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">ConfigurationCustomizer</span> <span class="token function">configurationCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ConfigurationCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">Configuration</span> configuration<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                configuration<span class="token punctuation">.</span><span class="token function">setMapUnderscoreToCamelCase</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>


</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code>使用<span class="token class-name">MapperScan</span>批量扫描所有的<span class="token class-name">Mapper</span>接口；
<span class="token annotation punctuation">@MapperScan</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">&quot;com.atguigu.springboot.mapper&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringBoot06DataMybatisApplication</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">SpringBoot06DataMybatisApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>配置文件版</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">mybatis</span><span class="token punctuation">:</span>
    <span class="token key atrule">config‐location</span><span class="token punctuation">:</span> classpath<span class="token punctuation">:</span>mybatis/mybatis‐config.xml 指定全局配置文件的位置
    <span class="token key atrule">mapper‐locations</span><span class="token punctuation">:</span> classpath<span class="token punctuation">:</span>mybatis/mapper/<span class="token important">*.xml</span> 指定sql映射文件的位置

</code></pre></div></li></ol> <blockquote><p><a href="http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/" target="_blank" rel="noopener noreferrer">官网教程<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h2 id="_4、整合springdata-jpa"><a href="#_4、整合springdata-jpa" class="header-anchor">#</a> 4、整合SpringData JPA</h2> <ol><li><p>编写一个实体类（bean）和数据表进行映射，并且配置好映射关系；</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//使用JPA注解配置映射关系</span>
<span class="token annotation punctuation">@Entity</span> <span class="token comment">//告诉JPA这是一个实体类（和数据表映射的类）</span>
<span class="token annotation punctuation">@Table</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span> <span class="token comment">//@Table来指定和哪个数据表对应;如果省略默认表名就是user；</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Id</span> <span class="token comment">//这是一个主键</span>
    <span class="token annotation punctuation">@GeneratedValue</span><span class="token punctuation">(</span>strategy <span class="token operator">=</span> <span class="token class-name">GenerationType</span><span class="token punctuation">.</span>IDENTITY<span class="token punctuation">)</span><span class="token comment">//自增主键</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> id<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Column</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;last_name&quot;</span><span class="token punctuation">,</span>length <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token comment">//这是和数据表对应的一个列</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> lastName<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Column</span> <span class="token comment">//省略默认列名就是属性名</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> email<span class="token punctuation">;</span>
</code></pre></div></li> <li><p>编写一个Dao接口来操作实体类对应的数据表（Repository）</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token comment">//继承JpaRepository来完成对数据库的操作</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserRepository</span> <span class="token keyword">extends</span> <span class="token class-name">JpaRepository</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">,</span><span class="token class-name">Integer</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>基本的配置JpaProperties</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">spring</span><span class="token punctuation">:</span>
<span class="token key atrule">jpa</span><span class="token punctuation">:</span>
<span class="token key atrule">hibernate</span><span class="token punctuation">:</span>
<span class="token comment"># 更新或者创建数据表结构</span>
<span class="token key atrule">ddl‐auto</span><span class="token punctuation">:</span> update
<span class="token comment"># 控制台显示SQL</span>
<span class="token key atrule">show‐sql</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
</code></pre></div><hr></li></ol> <h1 id="六、启动配置原理"><a href="#六、启动配置原理" class="header-anchor">#</a> 六、启动配置原理</h1> <p>几个重要的事件回调机制</p> <p>配置在META-INF/spring.factories</p> <p><strong>ApplicationContextInitializer</strong></p> <p><strong>SpringApplicationRunListener</strong></p> <p>只需要放在ioc容器中<strong>ApplicationRunner CommandLineRunner</strong></p> <p>启动流程：</p> <h3 id="_1、创建springapplication对象"><a href="#_1、创建springapplication对象" class="header-anchor">#</a> <strong>1</strong>、创建<strong>SpringApplication</strong>对象</h3> <div class="language-java extra-class"><pre class="language-java"><code>
    <span class="token function">initialize</span><span class="token punctuation">(</span>sources<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">initialize</span><span class="token punctuation">(</span><span class="token class-name">Object</span><span class="token punctuation">[</span><span class="token punctuation">]</span> sources<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//保存主配置类</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>sources <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> sources<span class="token punctuation">.</span>length <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>sources<span class="token punctuation">.</span><span class="token function">addAll</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">asList</span><span class="token punctuation">(</span>sources<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
<span class="token comment">//判断当前是否一个web应用</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>webEnvironment <span class="token operator">=</span> <span class="token function">deduceWebEnvironment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//从类路径下找到META‐INF/spring.factories配置的所有ApplicationContextInitializer；然后保存起</span>
        来
        <span class="token function">setInitializers</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">Collection</span><span class="token punctuation">)</span> <span class="token function">getSpringFactoriesInstances</span><span class="token punctuation">(</span>
                <span class="token class-name">ApplicationContextInitializer</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//从类路径下找到ETA‐INF/spring.factories配置的所有ApplicationListener</span>
        <span class="token function">setListeners</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">Collection</span><span class="token punctuation">)</span> <span class="token function">getSpringFactoriesInstances</span><span class="token punctuation">(</span><span class="token class-name">ApplicationListener</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//从多个配置类中找到有main方法的主配置类</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>mainApplicationClass <span class="token operator">=</span> <span class="token function">deduceMainApplicationClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre></div><h3 id="_2、运行run方法"><a href="#_2、运行run方法" class="header-anchor">#</a> <strong>2</strong>、运行<strong>run</strong>方法</h3> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token class-name">ConfigurableApplicationContext</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">StopWatch</span> stopWatch <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">StopWatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        stopWatch<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">ConfigurableApplicationContext</span> context <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token class-name">FailureAnalyzers</span> analyzers <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token function">configureHeadlessProperty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//获取SpringApplicationRunListeners；从类路径下META‐INF/spring.factories</span>
        <span class="token class-name">SpringApplicationRunListeners</span> listeners <span class="token operator">=</span> <span class="token function">getRunListeners</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//回调所有的获取SpringApplicationRunListener.starting()方法</span>
        listeners<span class="token punctuation">.</span><span class="token function">starting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token comment">//封装命令行参数</span>
            <span class="token class-name">ApplicationArguments</span> applicationArguments <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DefaultApplicationArguments</span><span class="token punctuation">(</span>
                    args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//准备环境</span>
            <span class="token class-name">ConfigurableEnvironment</span> environment <span class="token operator">=</span> <span class="token function">prepareEnvironment</span><span class="token punctuation">(</span>listeners<span class="token punctuation">,</span>
                    applicationArguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//创建环境完成后回调SpringApplicationRunListener.environmentPrepared()；表示环境准</span>
            备完成
            <span class="token class-name">Banner</span> printedBanner <span class="token operator">=</span> <span class="token function">printBanner</span><span class="token punctuation">(</span>environment<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//创建ApplicationContext；决定创建web的ioc还是普通的ioc</span>
            context <span class="token operator">=</span> <span class="token function">createApplicationContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            analyzers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FailureAnalyzers</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//准备上下文环境;将environment保存到ioc中；而且applyInitializers()；</span>
<span class="token comment">//applyInitializers()：回调之前保存的所有的ApplicationContextInitializer的initialize方法</span>
<span class="token comment">//回调所有的SpringApplicationRunListener的contextPrepared()；</span>
<span class="token comment">//</span>
            <span class="token function">prepareContext</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> environment<span class="token punctuation">,</span> listeners<span class="token punctuation">,</span> applicationArguments<span class="token punctuation">,</span>
                    printedBanner<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded（）；</span>
<span class="token comment">//s刷新容器；ioc容器初始化（如果是web应用还会创建嵌入式的Tomcat）；Spring注解版</span>
<span class="token comment">//扫描，创建，加载所有组件的地方；（配置类，组件，自动配置）</span>
            <span class="token function">refreshContext</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调</span>
<span class="token comment">//ApplicationRunner先回调，CommandLineRunner再回调</span>
            <span class="token function">afterRefresh</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> applicationArguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//所有的SpringApplicationRunListener回调finished方法</span>
            listeners<span class="token punctuation">.</span><span class="token function">finished</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            stopWatch<span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>logStartupInfo<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">new</span> <span class="token class-name">StartupInfoLogger</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>mainApplicationClass<span class="token punctuation">)</span>
                        <span class="token punctuation">.</span><span class="token function">logStarted</span><span class="token punctuation">(</span><span class="token function">getApplicationLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stopWatch<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
<span class="token comment">//整个SpringBoot应用启动完成以后返回启动的ioc容器；</span>
            <span class="token keyword">return</span> context<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Throwable</span> ex<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">handleRunFailure</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> listeners<span class="token punctuation">,</span> analyzers<span class="token punctuation">,</span> ex<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">IllegalStateException</span><span class="token punctuation">(</span>ex<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

</code></pre></div><h3 id="_3、事件监听机制"><a href="#_3、事件监听机制" class="header-anchor">#</a> <strong>3</strong>、事件监听机制</h3> <p>配置在META-INF/spring.factories <strong>ApplicationContextInitializer</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloApplicationContextInitializer</span> <span class="token keyword">implements</span>
    <span class="token class-name">ApplicationContextInitializer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ConfigurableApplicationContext</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">initialize</span><span class="token punctuation">(</span><span class="token class-name">ConfigurableApplicationContext</span> applicationContext<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    				<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;ApplicationContextInitializer...initialize...&quot;</span><span class="token operator">+</span>applicationContext<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><h6 id="springapplicationrunlistener"><a href="#springapplicationrunlistener" class="header-anchor">#</a> SpringApplicationRunListener</h6> <p>配置（META-INF/spring.factories）</p> <div class="language-xml extra-class"><pre class="language-xml"><code>org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener

</code></pre></div><p>只需要放在ioc容器中</p> <p><strong>ApplicationRunner</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
   <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloApplicationRunner</span> <span class="token keyword">implements</span> <span class="token class-name">ApplicationRunner</span> <span class="token punctuation">{</span>
   <span class="token annotation punctuation">@Override</span>
   <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">ApplicationArguments</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
   <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;ApplicationRunner...run....&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><p><strong>CommandLineRunner</strong></p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloCommandLineRunner</span> <span class="token keyword">implements</span> <span class="token class-name">CommandLineRunner</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;CommandLineRunner...run...&quot;</span><span class="token operator">+</span> <span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">asList</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><hr> <h1 id="七、自定义starter"><a href="#七、自定义starter" class="header-anchor">#</a> 七、自定义starter</h1> <p><strong>starter：</strong></p> <p>1、这个场景需要使用到的依赖是什么？</p> <p>2、如何编写自动配置</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span> <span class="token comment">//指定这个类是一个配置类</span>
<span class="token annotation punctuation">@ConditionalOnXXX</span> <span class="token comment">//在指定条件成立的情况下自动配置类生效</span>
<span class="token annotation punctuation">@AutoConfigureAfter</span> <span class="token comment">//指定自动配置类的顺序</span>
<span class="token annotation punctuation">@Bean</span> <span class="token comment">//给容器中添加组件</span>
<span class="token annotation punctuation">@ConfigurationPropertie</span>结合相关xxxProperties类来绑定相关的配置
<span class="token annotation punctuation">@EnableConfigurationProperties</span> <span class="token comment">//让xxxProperties生效加入到容器中</span>
自动配置类要能加载
将需要启动就加载的自动配置类，配置在META‐INF<span class="token operator">/</span>spring<span class="token punctuation">.</span>factories
org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span><span class="token class-name">EnableAutoConfiguration</span><span class="token operator">=</span>\
org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>admin<span class="token punctuation">.</span><span class="token class-name">SpringApplicationAdminJmxAutoConfiguration</span><span class="token punctuation">,</span>\
org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>aop<span class="token punctuation">.</span><span class="token class-name">AopAutoConfiguration</span><span class="token punctuation">,</span>\
</code></pre></div><p>3、模式：</p> <p>启动器只用来做依赖导入； 专门来写一个自动配置模块；</p> <p>启动器依赖自动配置；别人只需要引入启动器（starter）</p> <p>mybatis-spring-boot-starter；自定义启动器名-spring-boot-starter</p> <p>步骤：</p> <p>1）、启动器模块</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF‐8&quot;?&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.w3.org/2001/XMLSchema‐instance<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven‐4.0.0.xsd<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>modelVersion</span><span class="token punctuation">&gt;</span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>modelVersion</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.atguigu.starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>atguigu‐spring‐boot‐starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.0‐SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐启动器‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐引入自动配置模块‐‐</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.atguigu.starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>atguigu‐spring‐boot‐starter‐autoconfigurer<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>0.0.1‐SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>project</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>2）、自动配置模块</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF‐8&quot;?&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>project</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://maven.apache.org/POM/4.0.0<span class="token punctuation">&quot;</span></span>
<span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.w3.org/2001/XMLSchema‐instance<span class="token punctuation">&quot;</span></span>
<span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven‐
4.0.0.xsd<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>modelVersion</span><span class="token punctuation">&gt;</span></span>4.0.0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>modelVersion</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.atguigu.starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>atguigu‐spring‐boot‐starter‐autoconfigurer<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>0.0.1‐SNAPSHOT<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>packaging</span><span class="token punctuation">&gt;</span></span>jar<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>packaging</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>name</span><span class="token punctuation">&gt;</span></span>atguigu‐spring‐boot‐starter‐autoconfigurer<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>name</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>description</span><span class="token punctuation">&gt;</span></span>Demo project for Spring Boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>description</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter‐parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.5.10.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>relativePath</span><span class="token punctuation">/&gt;</span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐</span> <span class="token attr-name">lookup</span> <span class="token attr-name">parent</span> <span class="token attr-name">from</span> <span class="token attr-name">repository</span> <span class="token attr-name">‐‐</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>properties</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>project.build.sourceEncoding</span><span class="token punctuation">&gt;</span></span>UTF‐8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>project.build.sourceEncoding</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>project.reporting.outputEncoding</span><span class="token punctuation">&gt;</span></span>UTF‐8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>project.reporting.outputEncoding</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>java.version</span><span class="token punctuation">&gt;</span></span>1.8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>java.version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>properties</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>!‐‐引入spring‐boot‐starter；所有starter的基本配置‐‐</span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
       <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
       <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring‐boot‐starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>project</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>atguigu<span class="token punctuation">.</span>starter</span><span class="token punctuation">;</span>
        <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>context<span class="token punctuation">.</span>properties<span class="token punctuation">.</span></span><span class="token class-name">ConfigurationProperties</span><span class="token punctuation">;</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;atguigu.hello&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloProperties</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> prefix<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> suffix<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getPrefix</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> prefix<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPrefix</span><span class="token punctuation">(</span><span class="token class-name">String</span> prefix<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>prefix <span class="token operator">=</span> prefix<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getSuffix</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> suffix<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSuffix</span><span class="token punctuation">(</span><span class="token class-name">String</span> suffix<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>suffix <span class="token operator">=</span> suffix<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>atguigu<span class="token punctuation">.</span>starter</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloService</span> <span class="token punctuation">{</span>
    <span class="token class-name">HelloProperties</span> helloProperties<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token class-name">HelloProperties</span> <span class="token function">getHelloProperties</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> helloProperties<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setHelloProperties</span><span class="token punctuation">(</span><span class="token class-name">HelloProperties</span> helloProperties<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>helloProperties <span class="token operator">=</span> helloProperties<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">sayHellAtguigu</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> helloProperties<span class="token punctuation">.</span><span class="token function">getPrefix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">&quot;‐&quot;</span> <span class="token operator">+</span>name <span class="token operator">+</span> helloProperties<span class="token punctuation">.</span><span class="token function">getSuffix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>atguigu<span class="token punctuation">.</span>starter</span><span class="token punctuation">;</span>
       <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
       <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>condition<span class="token punctuation">.</span></span><span class="token class-name">ConditionalOnWebApplication</span><span class="token punctuation">;</span>
       <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>context<span class="token punctuation">.</span>properties<span class="token punctuation">.</span></span><span class="token class-name">EnableConfigurationProperties</span><span class="token punctuation">;</span>
       <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span>
       <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ConditionalOnWebApplication</span> <span class="token comment">//web应用才生效</span>
<span class="token annotation punctuation">@EnableConfigurationProperties</span><span class="token punctuation">(</span><span class="token class-name">HelloProperties</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HelloServiceAutoConfiguration</span> <span class="token punctuation">{</span>
   <span class="token annotation punctuation">@Autowired</span>
   <span class="token class-name">HelloProperties</span> helloProperties<span class="token punctuation">;</span>
   <span class="token annotation punctuation">@Bean</span>
   <span class="token keyword">public</span> <span class="token class-name">HelloService</span> <span class="token function">helloService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
       <span class="token class-name">HelloService</span> service <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HelloService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       service<span class="token punctuation">.</span><span class="token function">setHelloProperties</span><span class="token punctuation">(</span>helloProperties<span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token keyword">return</span> service<span class="token punctuation">;</span>
   <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p><a href="https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/#boot-features-developing-%20web-applications" target="_blank" rel="noopener noreferrer">SpringBoot官方文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p>《尚硅谷视频笔记》</p></blockquote></div> <footer class="page-edit" style="display:none;"><!----> <!----></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-db14854a data-v-db14854a><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-db14854a><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-db14854a></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-db14854a></path></svg></div><!----></div></div>
    <script src="/assets/js/app.447d4224.js" defer></script><script src="/assets/js/3.9d76740c.js" defer></script><script src="/assets/js/1.c4fd7d2e.js" defer></script><script src="/assets/js/88.2a423212.js" defer></script>
  </body>
</html>
